multiply two small integers, getting both the high and low bits.
| 3629 | |
| 3630 | // multiply two small integers, getting both the high and low bits. |
| 3631 | fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb |
| 3632 | scalar_mul(limb x, limb y, limb &carry) noexcept { |
| 3633 | #ifdef FASTFLOAT_64BIT_LIMB |
| 3634 | #if defined(__SIZEOF_INT128__) |
| 3635 | // GCC and clang both define it as an extension. |
| 3636 | __uint128_t z = __uint128_t(x) * __uint128_t(y) + __uint128_t(carry); |
| 3637 | carry = limb(z >> limb_bits); |
| 3638 | return limb(z); |
| 3639 | #else |
| 3640 | // fallback, no native 128-bit integer multiplication with carry. |
| 3641 | // on msvc, this optimizes identically, somehow. |
| 3642 | value128 z = full_multiplication(x, y); |
| 3643 | bool overflow; |
| 3644 | z.low = scalar_add(z.low, carry, overflow); |
| 3645 | z.high += uint64_t(overflow); // cannot overflow |
| 3646 | carry = z.high; |
| 3647 | return z.low; |
| 3648 | #endif |
| 3649 | #else |
| 3650 | uint64_t z = uint64_t(x) * uint64_t(y) + uint64_t(carry); |
| 3651 | carry = limb(z >> limb_bits); |
| 3652 | return limb(z); |
| 3653 | #endif |
| 3654 | } |
| 3655 | |
| 3656 | // add scalar value to bigint starting from offset. |
| 3657 | // used in grade school multiplication |
no test coverage detected