Bug 1558538 - BigInt-to-Number conversion is rather borken. r=wingo

Differential Revision: https://phabricator.services.mozilla.com/D34678

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jeff Walden 2019-06-19 18:39:02 +00:00
Родитель d7a28a9a95
Коммит c69f589086
2 изменённых файлов: 332 добавлений и 41 удалений

Просмотреть файл

@ -0,0 +1,187 @@
// |reftest| skip-if(!this.hasOwnProperty("BigInt"))
// Any copyright is dedicated to the Public Domain.
// https://creativecommons.org/licenses/publicdomain/
/**
* Simple single-Digit on x64, double-Digit on x86 tests.
*/
assertEq(BigInt(Number(2n**53n - 2n)), 2n**53n - 2n);
assertEq(BigInt(Number(2n**53n - 1n)), 2n**53n - 1n);
assertEq(BigInt(Number(2n**53n)), 2n**53n);
assertEq(BigInt(Number(2n**53n + 1n)), 2n**53n);
assertEq(BigInt(Number(2n**53n + 2n)), 2n**53n + 2n);
assertEq(BigInt(Number(2n**53n + 3n)), 2n**53n + 4n);
assertEq(BigInt(Number(2n**53n + 4n)), 2n**53n + 4n);
assertEq(BigInt(Number(2n**53n + 5n)), 2n**53n + 4n);
assertEq(BigInt(Number(2n**53n + 6n)), 2n**53n + 6n);
assertEq(BigInt(Number(2n**53n + 7n)), 2n**53n + 8n);
assertEq(BigInt(Number(2n**53n + 8n)), 2n**53n + 8n);
assertEq(BigInt(Number(2n**54n - 4n)), 2n**54n - 4n);
assertEq(BigInt(Number(2n**54n - 3n)), 2n**54n - 4n);
assertEq(BigInt(Number(2n**54n - 2n)), 2n**54n - 2n);
assertEq(BigInt(Number(2n**54n - 1n)), 2n**54n);
assertEq(BigInt(Number(2n**54n)), 2n**54n);
assertEq(BigInt(Number(2n**54n + 1n)), 2n**54n);
assertEq(BigInt(Number(2n**54n + 2n)), 2n**54n);
assertEq(BigInt(Number(2n**54n + 3n)), 2n**54n + 4n);
assertEq(BigInt(Number(2n**54n + 4n)), 2n**54n + 4n);
assertEq(BigInt(Number(2n**54n + 5n)), 2n**54n + 4n);
assertEq(BigInt(Number(2n**54n + 6n)), 2n**54n + 8n);
assertEq(BigInt(Number(2n**54n + 7n)), 2n**54n + 8n);
assertEq(BigInt(Number(2n**54n + 8n)), 2n**54n + 8n);
assertEq(BigInt(Number(2n**55n - 8n)), 2n**55n - 8n);
assertEq(BigInt(Number(2n**55n - 7n)), 2n**55n - 8n);
assertEq(BigInt(Number(2n**55n - 6n)), 2n**55n - 8n);
assertEq(BigInt(Number(2n**55n - 5n)), 2n**55n - 4n);
assertEq(BigInt(Number(2n**55n - 4n)), 2n**55n - 4n);
assertEq(BigInt(Number(2n**55n - 3n)), 2n**55n - 4n);
assertEq(BigInt(Number(2n**55n - 2n)), 2n**55n);
assertEq(BigInt(Number(2n**55n - 1n)), 2n**55n);
assertEq(BigInt(Number(2n**55n)), 2n**55n);
assertEq(BigInt(Number(2n**55n + 1n)), 2n**55n);
assertEq(BigInt(Number(2n**55n + 2n)), 2n**55n);
assertEq(BigInt(Number(2n**55n + 3n)), 2n**55n);
assertEq(BigInt(Number(2n**55n + 4n)), 2n**55n);
assertEq(BigInt(Number(2n**55n + 5n)), 2n**55n + 8n);
assertEq(BigInt(Number(2n**55n + 6n)), 2n**55n + 8n);
assertEq(BigInt(Number(2n**55n + 7n)), 2n**55n + 8n);
assertEq(BigInt(Number(2n**55n + 8n)), 2n**55n + 8n);
assertEq(BigInt(Number(2n**55n + 9n)), 2n**55n + 8n);
assertEq(BigInt(Number(2n**55n + 10n)), 2n**55n + 8n);
assertEq(BigInt(Number(2n**55n + 11n)), 2n**55n + 8n);
assertEq(BigInt(Number(2n**55n + 12n)), 2n**55n + 16n);
assertEq(BigInt(Number(2n**55n + 13n)), 2n**55n + 16n);
assertEq(BigInt(Number(2n**55n + 14n)), 2n**55n + 16n);
assertEq(BigInt(Number(2n**55n + 15n)), 2n**55n + 16n);
assertEq(BigInt(Number(2n**55n + 16n)), 2n**55n + 16n);
/**
* Simple double-Digit on x64, triple-Digit on x86 tests.
*/
// The tests below that aren't subtracting bits will have no bits in the
// ultimate significand from the most-significant digit (because of the implicit
// one being excluded).
assertEq(BigInt(Number(2n**64n - 2n**11n)), 2n**64n - 2n**11n);
assertEq(BigInt(Number(2n**64n - 2n**11n + 2n**10n - 1n)), 2n**64n - 2n**11n);
assertEq(BigInt(Number(2n**64n - 2n**11n + 2n**10n)), 2n**64n);
assertEq(BigInt(Number(2n**64n - 2n**10n)), 2n**64n);
assertEq(BigInt(Number(2n**64n)), 2n**64n);
assertEq(BigInt(Number(2n**64n + 1n)), 2n**64n);
assertEq(BigInt(Number(2n**64n + 2n**5n)), 2n**64n);
assertEq(BigInt(Number(2n**64n + 2n**10n)), 2n**64n);
assertEq(BigInt(Number(2n**64n + 2n**11n)), 2n**64n);
assertEq(BigInt(Number(2n**64n + 2n**11n + 1n)), 2n**64n + 2n**12n);
assertEq(BigInt(Number(2n**64n + 2n**12n)), 2n**64n + 2n**12n);
assertEq(BigInt(Number(2n**64n + 2n**12n + 1n)), 2n**64n + 2n**12n);
assertEq(BigInt(Number(2n**64n + 2n**12n + 2n**5n)), 2n**64n + 2n**12n);
assertEq(BigInt(Number(2n**64n + 2n**12n + 2n**10n)), 2n**64n + 2n**12n);
assertEq(BigInt(Number(2n**64n + 2n**12n + 2n**11n - 1n)), 2n**64n + 2n**12n);
assertEq(BigInt(Number(2n**64n + 2n**12n + 2n**11n)), 2n**64n + 2n**13n);
assertEq(BigInt(Number(2n**64n + 2n**12n + 2n**11n + 1n)), 2n**64n + 2n**13n);
// These tests *will* have a bit from the most-significant digit in the ultimate
// significand.
assertEq(BigInt(Number(2n**65n - 2n**12n)), 2n**65n - 2n**12n);
assertEq(BigInt(Number(2n**65n - 2n**12n + 2n**11n - 1n)), 2n**65n - 2n**12n);
assertEq(BigInt(Number(2n**65n - 2n**12n + 2n**11n)), 2n**65n);
assertEq(BigInt(Number(2n**65n - 2n**11n)), 2n**65n);
assertEq(BigInt(Number(2n**65n)), 2n**65n);
assertEq(BigInt(Number(2n**65n + 1n)), 2n**65n);
assertEq(BigInt(Number(2n**65n + 2n**5n)), 2n**65n);
assertEq(BigInt(Number(2n**65n + 2n**11n)), 2n**65n);
assertEq(BigInt(Number(2n**65n + 2n**12n)), 2n**65n);
assertEq(BigInt(Number(2n**65n + 2n**12n + 1n)), 2n**65n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**13n)), 2n**65n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**13n + 1n)), 2n**65n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**13n + 2n**5n)), 2n**65n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**13n + 2n**11n)), 2n**65n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**13n + 2n**12n - 1n)), 2n**65n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**13n + 2n**12n)), 2n**65n + 2n**14n);
assertEq(BigInt(Number(2n**65n + 2n**13n + 2n**12n + 1n)), 2n**65n + 2n**14n);
// ...and in these tests, the contributed bit from the most-significant digit
// is additionally nonzero.
assertEq(BigInt(Number(2n**65n + 2n**64n)), 2n**65n + 2n**64n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 1n)), 2n**65n + 2n**64n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**5n)), 2n**65n + 2n**64n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**11n)), 2n**65n + 2n**64n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**12n)), 2n**65n + 2n**64n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**12n + 1n)), 2n**65n + 2n**64n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**13n)), 2n**65n + 2n**64n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**13n + 1n)), 2n**65n + 2n**64n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**13n + 2n**5n)), 2n**65n + 2n**64n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**13n + 2n**11n)), 2n**65n + 2n**64n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**13n + 2n**12n - 1n)), 2n**65n + 2n**64n + 2n**13n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**13n + 2n**12n)), 2n**65n + 2n**64n + 2n**14n);
assertEq(BigInt(Number(2n**65n + 2n**64n + 2n**13n + 2n**12n + 1n)), 2n**65n + 2n**64n + 2n**14n);
/**
* Versions of the testing above with all the high-order bits massively bumped
* upward to test that super-low bits, not just bits in high digits, are
* properly accounted for in rounding.
*/
// The tests below that aren't subtracting bits will have no bits in the
// ultimate significand from the most-significant digit (because of the implicit
// one being excluded).
assertEq(BigInt(Number(2n**940n - 2n**887n + 1n)), 2n**940n - 2n**887n);
assertEq(BigInt(Number(2n**940n - 2n**887n + 2n**886n - 1n)), 2n**940n - 2n**887n);
assertEq(BigInt(Number(2n**940n - 2n**887n + 2n**886n)), 2n**940n);
assertEq(BigInt(Number(2n**940n - 2n**886n)), 2n**940n);
assertEq(BigInt(Number(2n**940n)), 2n**940n);
assertEq(BigInt(Number(2n**940n + 1n)), 2n**940n);
assertEq(BigInt(Number(2n**940n + 2n**880n)), 2n**940n);
assertEq(BigInt(Number(2n**940n + 2n**885n)), 2n**940n);
assertEq(BigInt(Number(2n**940n + 2n**887n)), 2n**940n);
assertEq(BigInt(Number(2n**940n + 2n**887n + 1n)), 2n**940n + 2n**888n);
assertEq(BigInt(Number(2n**940n + 2n**888n)), 2n**940n + 2n**888n);
assertEq(BigInt(Number(2n**940n + 2n**888n + 1n)), 2n**940n + 2n**888n);
assertEq(BigInt(Number(2n**940n + 2n**888n + 2n**5n)), 2n**940n + 2n**888n);
assertEq(BigInt(Number(2n**940n + 2n**888n + 2n**12n)), 2n**940n + 2n**888n);
assertEq(BigInt(Number(2n**940n + 2n**888n + 2n**887n - 1n)), 2n**940n + 2n**888n);
assertEq(BigInt(Number(2n**940n + 2n**888n + 2n**887n)), 2n**940n + 2n**889n);
assertEq(BigInt(Number(2n**940n + 2n**888n + 2n**887n + 1n)), 2n**940n + 2n**889n);
// These tests *will* have a bit from the most-significant digit in the ultimate
// significand.
assertEq(BigInt(Number(2n**941n - 2n**888n)), 2n**941n - 2n**888n);
assertEq(BigInt(Number(2n**941n - 2n**888n + 2n**887n - 1n)), 2n**941n - 2n**888n);
assertEq(BigInt(Number(2n**941n - 2n**888n + 2n**887n)), 2n**941n);
assertEq(BigInt(Number(2n**941n - 2n**887n)), 2n**941n);
assertEq(BigInt(Number(2n**941n)), 2n**941n);
assertEq(BigInt(Number(2n**941n + 1n)), 2n**941n);
assertEq(BigInt(Number(2n**941n + 2n**881n)), 2n**941n);
assertEq(BigInt(Number(2n**941n + 2n**886n)), 2n**941n);
assertEq(BigInt(Number(2n**941n + 2n**888n)), 2n**941n);
assertEq(BigInt(Number(2n**941n + 2n**888n + 1n)), 2n**941n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**889n)), 2n**941n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**889n + 1n)), 2n**941n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**889n + 2n**5n)), 2n**941n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**889n + 2n**12n)), 2n**941n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**889n + 2n**888n - 1n)), 2n**941n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**889n + 2n**888n)), 2n**941n + 2n**890n);
assertEq(BigInt(Number(2n**941n + 2n**889n + 2n**888n + 1n)), 2n**941n + 2n**890n);
// ...and in these tests, the contributed bit from the most-significant digit
// is additionally nonzero.
assertEq(BigInt(Number(2n**941n + 2n**940n)), 2n**941n + 2n**940n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 1n)), 2n**941n + 2n**940n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**881n)), 2n**941n + 2n**940n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**886n)), 2n**941n + 2n**940n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**888n)), 2n**941n + 2n**940n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**888n + 1n)), 2n**941n + 2n**940n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**889n)), 2n**941n + 2n**940n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**889n + 1n)), 2n**941n + 2n**940n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**889n + 2n**5n)), 2n**941n + 2n**940n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**889n + 2n**12n)), 2n**941n + 2n**940n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**889n + 2n**888n - 1n)), 2n**941n + 2n**940n + 2n**889n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**889n + 2n**888n)), 2n**941n + 2n**940n + 2n**890n);
assertEq(BigInt(Number(2n**941n + 2n**940n + 2n**889n + 2n**888n + 1n)), 2n**941n + 2n**940n + 2n**890n);
if (typeof reportCompare === "function")
reportCompare(true, true);

Просмотреть файл

@ -2726,8 +2726,9 @@ double BigInt::numberValue(BigInt* x) {
size_t length = x->digitLength();
MOZ_ASSERT(length != 0);
// Fast path for the likely-common case of up to a uint64_t of magnitude
// that doesn't exceed integral precision in IEEE-754.
// Fast path for the likely-common case of up to a uint64_t of magnitude not
// exceeding integral precision in IEEE-754. (Note that we *depend* on this
// optimization being performed further down.)
if (length <= 64 / DigitBits) {
uint64_t magnitude = x->digit(0);
if (DigitBits == 32 && length > 1) {
@ -2760,62 +2761,165 @@ double BigInt::numberValue(BigInt* x) {
const uint8_t msdIgnoredBits = msdLeadingZeroes + 1;
const uint8_t msdIncludedBits = DigitBits - msdIgnoredBits;
uint8_t bitsFilled = msdIncludedBits;
// We compute the final mantissa of the result, shifted upward to the top of
// the `uint64_t` space -- plus an extra bit to detect potential rounding.
constexpr uint8_t BitsNeededForShiftedMantissa = SignificandWidth + 1;
// Shift `msd`'s contributed bits upward to remove high-order zeroes and
// the highest set bit (which is implicit in IEEE-754 integral values so
// must be removed) and to add low-order zeroes.
// Shift `msd`'s contributed bits upward to remove high-order zeroes and the
// highest set bit (which is implicit in IEEE-754 integral values so must be
// removed) and to add low-order zeroes. (Lower-order garbage bits are
// discarded when `shiftedMantissa` is converted to a real mantissa.)
uint64_t shiftedMantissa =
msdIncludedBits == 0 ? 0 : uint64_t(msd) << (64 - msdIncludedBits);
// Add in bits from the next one or two digits if `msd` didn't contain all
// bits necessary to define the result. (The extra bit allows us to
// properly round an inexact overall result.) Any lower bits that are
// uselessly set will be shifted away when `shiftedMantissa` is converted to
// a real mantissa.
if (bitsFilled < SignificandWidth + 1) {
// If the extra bit is set, correctly rounding the result may require
// examining all lower-order bits. Also compute 1) the index of the Digit
// storing the extra bit, and 2) whether bits beneath the extra bit in that
// Digit are nonzero so we can round if needed.
size_t digitContainingExtraBit;
Digit bitsBeneathExtraBitInDigitContainingExtraBit;
// Add shifted bits to `shiftedMantissa` until we have a complete mantissa and
// an extra bit.
if (msdIncludedBits >= BitsNeededForShiftedMantissa) {
// DigitBits=64 (necessarily for msdIncludedBits ≥ SignificandWidth+1;
// | C++ compiler range analysis ought eliminate this
// | check on 32-bit)
// _________|__________
// / |
// msdIncludedBits
// ________|________
// / |
// [001···················|
// \_/\_____________/\__|
// | | |
// msdIgnoredBits | bits below the extra bit (may be no bits)
// BitsNeededForShiftedMantissa=SignificandWidth+1
digitContainingExtraBit = length - 1;
const uint8_t countOfBitsInDigitBelowExtraBit =
DigitBits - BitsNeededForShiftedMantissa - msdIgnoredBits;
bitsBeneathExtraBitInDigitContainingExtraBit =
msd & ((Digit(1) << countOfBitsInDigitBelowExtraBit) - 1);
} else {
MOZ_ASSERT(length >= 2,
"single-Digit numbers with this few bits should have been "
"handled by the fast-path above");
Digit second = x->digit(length - 2);
if (DigitBits == 32) {
shiftedMantissa |= uint64_t(second) << msdIgnoredBits;
bitsFilled += DigitBits;
if (DigitBits == 64) {
shiftedMantissa |= second >> msdIncludedBits;
digitContainingExtraBit = length - 2;
// msdIncludedBits + DigitBits
// ________|_________
// / |
// DigitBits=64
// msdIncludedBits |
// __|___ _____|___
// / \ / |
// [001········|···········|
// \_/\_____________/\___|
// | | |
// msdIgnoredBits | bits below the extra bit (always more than one)
// |
// BitsNeededForShiftedMantissa=SignificandWidth+1
const uint8_t countOfBitsInSecondDigitBelowExtraBit =
(msdIncludedBits + DigitBits) - BitsNeededForShiftedMantissa;
bitsBeneathExtraBitInDigitContainingExtraBit =
second << (DigitBits - countOfBitsInSecondDigitBelowExtraBit);
} else {
shiftedMantissa |= uint64_t(second) << msdIgnoredBits;
if (msdIncludedBits + DigitBits >= BitsNeededForShiftedMantissa) {
digitContainingExtraBit = length - 2;
// msdIncludedBits + DigitBits
// ______|________
// / |
// DigitBits=32
// msdIncludedBits |
// _|_ _____|___
// / \ / |
// [001·····|···········|
// \___________/\__|
// | |
// | bits below the extra bit (may be no bits)
// BitsNeededForShiftedMantissa=SignificandWidth+1
const uint8_t countOfBitsInSecondDigitBelowExtraBit =
(msdIncludedBits + DigitBits) - BitsNeededForShiftedMantissa;
bitsBeneathExtraBitInDigitContainingExtraBit =
second & ((Digit(1) << countOfBitsInSecondDigitBelowExtraBit) - 1);
} else {
MOZ_ASSERT(length >= 3,
"we must have at least three digits here, because "
"`msdIncludedBits + 32 < BitsNeededForShiftedMantissa` "
"guarantees `x < 2**53` -- and therefore the "
"MaxIntegralPrecisionDouble optimization above will have "
"handled two-digit cases");
// Add in bits from another digit, if any, if we still have unfilled
// significand bits.
if (bitsFilled < SignificandWidth + 1 && length >= 3) {
Digit third = x->digit(length - 3);
shiftedMantissa |= uint64_t(third) >> msdIncludedBits;
// The second and third 32-bit digits contributed 64 bits total, filling
// well beyond the mantissa.
bitsFilled = 64;
digitContainingExtraBit = length - 3;
// msdIncludedBits + DigitBits + DigitBits
// ____________|______________
// / |
// DigitBits=32
// msdIncludedBits | DigitBits=32
// _|_ _____|___ ____|____
// / \ / \ / |
// [001·····|···········|···········|
// \____________________/\_____|
// | |
// | bits below the extra bit
// BitsNeededForShiftedMantissa=SignificandWidth+1
static_assert(2 * DigitBits > BitsNeededForShiftedMantissa,
"two 32-bit digits should more than fill a mantissa");
const uint8_t countOfBitsInThirdDigitBelowExtraBit =
msdIncludedBits + 2 * DigitBits - BitsNeededForShiftedMantissa;
// Shift out the mantissa bits and the extra bit.
bitsBeneathExtraBitInDigitContainingExtraBit =
third << (DigitBits - countOfBitsInThirdDigitBelowExtraBit);
}
} else {
shiftedMantissa |= second >> msdIncludedBits;
// A full 64-bit digit's worth of bits (some from the most significant
// digit, the rest from the next) fills well beyond the mantissa.
bitsFilled = 64;
}
}
// Round the overall result, if necessary. (It's possible we don't need to
// round -- the number might not have enough bits to round.)
if (bitsFilled >= SignificandWidth + 1) {
constexpr uint64_t LeastSignificantBit = uint64_t(1)
<< (64 - SignificandWidth);
constexpr uint64_t ExtraBit = LeastSignificantBit >> 1;
constexpr uint64_t LeastSignificantBit = uint64_t(1)
<< (64 - SignificandWidth);
constexpr uint64_t ExtraBit = LeastSignificantBit >> 1;
// When the first bit outside the significand is set, the overall value
// is rounded: downward (i.e. no change to the bits) if the least
// significant bit in the significand is zero, upward if it instead is
// one.
if ((shiftedMantissa & ExtraBit) &&
(shiftedMantissa & LeastSignificantBit)) {
// We're rounding upward: add to the significand bits. If they
// overflow, the exponent must also be increased. If *that*
// overflows, return the appropriate infinity.
// The extra bit must be set for rounding to change the mantissa.
if ((shiftedMantissa & ExtraBit) != 0) {
bool shouldRoundUp;
if (shiftedMantissa & LeastSignificantBit) {
// If the lowest mantissa bit is set, it doesn't matter what lower bits
// are: nearest-even rounds up regardless.
shouldRoundUp = true;
} else {
// If the lowest mantissa bit is unset, *all* lower bits are relevant.
// All-zero bits below the extra bit situates `x` halfway between two
// values, and the nearest *even* value lies downward. But if any bit
// below the extra bit is set, `x` is closer to the rounded-up value.
shouldRoundUp = bitsBeneathExtraBitInDigitContainingExtraBit != 0;
if (!shouldRoundUp) {
while (digitContainingExtraBit-- > 0) {
if (x->digit(digitContainingExtraBit) != 0) {
shouldRoundUp = true;
break;
}
}
}
}
if (shouldRoundUp) {
// Add one to the significand bits. If they overflow, the exponent must
// also be increased. If *that* overflows, return the correct infinity.
uint64_t before = shiftedMantissa;
shiftedMantissa += ExtraBit;
if (shiftedMantissa < before) {