MCPcopy Create free account
hub / github.com/apache/arrow / ExtendAndMultiply

Function ExtendAndMultiply

cpp/src/arrow/util/basic_decimal.cc:533–564  ·  view source on GitHub ↗

Multiply two 64 bit word components into a 128 bit result, with high bits stored in hi and low bits in lo.

Source from the content-addressed store, hash-verified

531// Multiply two 64 bit word components into a 128 bit result, with high bits
532// stored in hi and low bits in lo.
533inline void ExtendAndMultiply(uint64_t x, uint64_t y, uint64_t* hi, uint64_t* lo) {
534 // Perform multiplication on two 64 bit words x and y into a 128 bit result
535 // by splitting up x and y into 32 bit high/low bit components,
536 // allowing us to represent the multiplication as
537 // x * y = x_lo * y_lo + x_hi * y_lo * 2^32 + y_hi * x_lo * 2^32
538 // + x_hi * y_hi * 2^64
539 //
540 // Now, consider the final output as lo_lo || lo_hi || hi_lo || hi_hi
541 // Therefore,
542 // lo_lo is (x_lo * y_lo)_lo,
543 // lo_hi is ((x_lo * y_lo)_hi + (x_hi * y_lo)_lo + (x_lo * y_hi)_lo)_lo,
544 // hi_lo is ((x_hi * y_hi)_lo + (x_hi * y_lo)_hi + (x_lo * y_hi)_hi)_hi,
545 // hi_hi is (x_hi * y_hi)_hi
546 const uint64_t x_lo = x & kInt32Mask;
547 const uint64_t y_lo = y & kInt32Mask;
548 const uint64_t x_hi = x >> 32;
549 const uint64_t y_hi = y >> 32;
550
551 const uint64_t t = x_lo * y_lo;
552 const uint64_t t_lo = t & kInt32Mask;
553 const uint64_t t_hi = t >> 32;
554
555 const uint64_t u = x_hi * y_lo + t_hi;
556 const uint64_t u_lo = u & kInt32Mask;
557 const uint64_t u_hi = u >> 32;
558
559 const uint64_t v = x_lo * y_hi + u_lo;
560 const uint64_t v_hi = v >> 32;
561
562 *hi = x_hi * y_hi + u_hi + v_hi;
563 *lo = (v << 32) + t_lo;
564}
565
566struct uint128_t {
567 uint128_t() {}

Callers 1

uint128_tClass · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected