From 48d4e3ea60966f1e2ef07f54fd42a63018e7f93e Mon Sep 17 00:00:00 2001 From: Clint Banzhaf Date: Sat, 22 Nov 2025 19:43:11 +0100 Subject: [PATCH 1/2] update --- include/CppCore.Test/Math/Util.h | 12 ++++++++++++ include/CppCore/Math/Util.h | 17 ++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/include/CppCore.Test/Math/Util.h b/include/CppCore.Test/Math/Util.h index 65b61bec..5c117e63 100644 --- a/include/CppCore.Test/Math/Util.h +++ b/include/CppCore.Test/Math/Util.h @@ -1415,6 +1415,18 @@ namespace CppCore { namespace Test { namespace Math if (!specials) return false; + // test some other special cases + uint64_t x = 0U; + for (size_t i = 0; i < 64U; i++) + { + x <<= 1; + x |= 1; + double d1 = CppCore::todouble(x); + double d2 = (double)x; + if (d1 != d2) + return false; + } + // test some random ones CppCore::Random::Default64 rnd; for (size_t i = 0; i < 100000; i++) diff --git a/include/CppCore/Math/Util.h b/include/CppCore/Math/Util.h index b145774c..5aab1c2b 100644 --- a/include/CppCore/Math/Util.h +++ b/include/CppCore/Math/Util.h @@ -1536,7 +1536,7 @@ namespace CppCore // build the zero (positive) sign bit and the exponent bits // exp is neg for 0-1022, zero for 1023 and pos above. // shift the exponent in place (52 bits mantissa) - const uint64_t exp = (uint64_t)(IH + 1023U) << 52; + uint64_t exp = (uint64_t)(IH + 1023U) << 52; // start mantissa building by left-shifting the high bit out of x. // this removes it and creates a fixed offset to the hidden highbit position in IEEE-754. @@ -1572,18 +1572,17 @@ namespace CppCore case FE_TONEAREST: // round up for upper range (break tie by only rounding odd up) man += ((lost > 2048U) | ((lost == 2048U) & man & 1U)); - - //if (_bittest((long*)&lost, 11)) - // man += ((lost & 2047) | (man & 1)) != 0; - - // if rounding overflowed into exp bits, increment exponent and remove overflow bit. - // disabled because just ORing the overflow into exp below gives same result here. - //if (man & MASKEXP) { exp++; man &= MASKMAN; } break; } + // if rounding overflowed into exp bits, + // increment exponent and remove overflow bit from mantissa + if (man & MASKEXP) { + exp += MASKHHI; + man &= MASKMAN; + } + // combine the exponent bits with the mantissa bits - // OR a possible overflow bit of mantissa into exponent const uint64_t ri = exp | man; return reinterpret_cast(ri); } From 2ec9c236374a041d179066c34f219ef98ff692f0 Mon Sep 17 00:00:00 2001 From: Clint Banzhaf Date: Sat, 22 Nov 2025 20:23:56 +0100 Subject: [PATCH 2/2] disable for bigint --- include/CppCore.Test/Math/BigInt.h | 3 ++- include/CppCore/Math/BigInt.h | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/CppCore.Test/Math/BigInt.h b/include/CppCore.Test/Math/BigInt.h index 9a020f5e..89c03367 100644 --- a/include/CppCore.Test/Math/BigInt.h +++ b/include/CppCore.Test/Math/BigInt.h @@ -205,6 +205,7 @@ namespace CppCore { namespace Test { namespace Math } INLINE static bool todouble128() { + /* // test low 64-bit ones that can be tested with double chast for (uint64_t i = 0; i <= 0x000000000000FFFFULL; i++) { @@ -244,7 +245,7 @@ namespace CppCore { namespace Test { namespace Math if (!specials128) return false; - + */ return true; } diff --git a/include/CppCore/Math/BigInt.h b/include/CppCore/Math/BigInt.h index 5fbe4268..0d9816fb 100644 --- a/include/CppCore/Math/BigInt.h +++ b/include/CppCore/Math/BigInt.h @@ -2575,8 +2575,9 @@ namespace CppCore /// /// Convert to IEEE-754 Double Precision + /// TODO: This has bugs and should not be used /// - constexpr INLINE explicit operator double () const + /*constexpr INLINE explicit operator double() const { constexpr uint32_t BITS = N8 * 8U; constexpr uint32_t LOSS = BITS - 52U; @@ -2602,10 +2603,10 @@ namespace CppCore los = man & LMSK; man >>= LOSS; man += ((los > LCMP) || ((los == LCMP) && ((uint32_t)man & 1U))); - exp |= (uint64_t)man; + exp |= (uint64_t)man; // this needs refactoring, see CppCore::todouble() return reinterpret_cast(exp); - } + }*/ /// /// Convert to Decimal String