From 54b8a2b094c1f8ec94acedcc89d314a7b90f572f Mon Sep 17 00:00:00 2001 From: Moustafa Raafat Date: Sun, 23 Oct 2022 16:46:35 +0100 Subject: [PATCH] LibCrypto: Add a way to compare UnsignedBigInteger with double This patch also make SignedBigInteger::compare_to_double make use of the new function. --- Tests/LibCrypto/TestBigInteger.cpp | 92 ++++++++++- .../LibCrypto/BigInt/SignedBigInteger.cpp | 156 ++---------------- .../LibCrypto/BigInt/SignedBigInteger.h | 8 +- .../LibCrypto/BigInt/UnsignedBigInteger.cpp | 145 ++++++++++++++++ .../LibCrypto/BigInt/UnsignedBigInteger.h | 8 + .../LibJS/Runtime/Temporal/ZonedDateTime.cpp | 2 +- Userland/Libraries/LibJS/Runtime/Value.cpp | 6 +- 7 files changed, 259 insertions(+), 158 deletions(-) diff --git a/Tests/LibCrypto/TestBigInteger.cpp b/Tests/LibCrypto/TestBigInteger.cpp index 3332cc065ec..d2103ae8cdd 100644 --- a/Tests/LibCrypto/TestBigInteger.cpp +++ b/Tests/LibCrypto/TestBigInteger.cpp @@ -660,9 +660,9 @@ TEST_CASE(test_negative_zero_is_not_allowed) } TEST_CASE(double_comparisons) { -#define EXPECT_LESS_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::SignedBigInteger::CompareResult::DoubleGreaterThanBigInt) -#define EXPECT_GREATER_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::SignedBigInteger::CompareResult::DoubleLessThanBigInt) -#define EXPECT_EQUAL_TO(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::SignedBigInteger::CompareResult::DoubleEqualsBigInt) +#define EXPECT_LESS_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleGreaterThanBigInt) +#define EXPECT_GREATER_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleLessThanBigInt) +#define EXPECT_EQUAL_TO(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleEqualsBigInt) { Crypto::SignedBigInteger zero { 0 }; EXPECT_EQUAL_TO(zero, 0.0); EXPECT_EQUAL_TO(zero, -0.0); @@ -687,6 +687,14 @@ EXPECT_EQUAL_TO(zero, -0.0); EXPECT_GREATER_THAN(one, -1.000001); } +{ + double double_infinity = HUGE_VAL; + VERIFY(isinf(double_infinity)); + Crypto::SignedBigInteger one { 1 }; + EXPECT_LESS_THAN(one, double_infinity); + EXPECT_GREATER_THAN(one, -double_infinity); +} + { double double_max_value = NumericLimits::max(); double double_below_max_value = nextafter(double_max_value, 0.0); @@ -938,18 +946,86 @@ TEST_CASE(bigint_from_double) #undef SURVIVES_ROUND_TRIP_SIGNED #undef SURVIVES_ROUND_TRIP_UNSIGNED } + +TEST_CASE(unsigned_bigint_double_comparisons) +{ +#define EXPECT_LESS_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleGreaterThanBigInt) +#define EXPECT_GREATER_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleLessThanBigInt) +#define EXPECT_EQUAL_TO(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleEqualsBigInt) + + { + Crypto::UnsignedBigInteger zero { 0 }; + EXPECT_EQUAL_TO(zero, 0.0); + EXPECT_EQUAL_TO(zero, -0.0); + } + + { + Crypto::UnsignedBigInteger one { 1 }; + EXPECT_EQUAL_TO(one, 1.0); + EXPECT_GREATER_THAN(one, -1.0); + EXPECT_GREATER_THAN(one, 0.5); + EXPECT_GREATER_THAN(one, -0.5); + EXPECT_LESS_THAN(one, 1.000001); + } + + { + double double_infinity = HUGE_VAL; + VERIFY(isinf(double_infinity)); + Crypto::UnsignedBigInteger one { 1 }; + EXPECT_LESS_THAN(one, double_infinity); + EXPECT_GREATER_THAN(one, -double_infinity); + } + + { + double double_max_value = NumericLimits::max(); + double double_below_max_value = nextafter(double_max_value, 0.0); + VERIFY(double_below_max_value < double_max_value); + VERIFY(double_below_max_value < (double_max_value - 1.0)); + auto max_value_in_bigint = Crypto::UnsignedBigInteger::from_base(16, "fffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"sv); + auto max_value_plus_one = max_value_in_bigint.plus(Crypto::UnsignedBigInteger { 1 }); + auto max_value_minus_one = max_value_in_bigint.minus(Crypto::UnsignedBigInteger { 1 }); + + auto below_max_value_in_bigint = Crypto::UnsignedBigInteger::from_base(16, "fffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"sv); + + EXPECT_EQUAL_TO(max_value_in_bigint, double_max_value); + EXPECT_LESS_THAN(max_value_minus_one, double_max_value); + EXPECT_GREATER_THAN(max_value_plus_one, double_max_value); + EXPECT_LESS_THAN(below_max_value_in_bigint, double_max_value); + + EXPECT_GREATER_THAN(max_value_in_bigint, double_below_max_value); + EXPECT_GREATER_THAN(max_value_minus_one, double_below_max_value); + EXPECT_GREATER_THAN(max_value_plus_one, double_below_max_value); + EXPECT_EQUAL_TO(below_max_value_in_bigint, double_below_max_value); + } + + { + double just_above_255 = bit_cast(0x406fe00000000001ULL); + double just_below_255 = bit_cast(0x406fdfffffffffffULL); + double double_255 = 255.0; + Crypto::UnsignedBigInteger bigint_255 { 255 }; + + EXPECT_EQUAL_TO(bigint_255, double_255); + EXPECT_GREATER_THAN(bigint_255, just_below_255); + EXPECT_LESS_THAN(bigint_255, just_above_255); + } + +#undef EXPECT_LESS_THAN +#undef EXPECT_GREATER_THAN +#undef EXPECT_EQUAL_TO +} + namespace AK { template<> -struct Formatter : Formatter { - ErrorOr format(FormatBuilder& builder, Crypto::SignedBigInteger::CompareResult const& compare_result) +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, Crypto::UnsignedBigInteger::CompareResult const& compare_result) { switch (compare_result) { - case Crypto::SignedBigInteger::CompareResult::DoubleEqualsBigInt: + case Crypto::UnsignedBigInteger::CompareResult::DoubleEqualsBigInt: return builder.put_string("Equals"sv); - case Crypto::SignedBigInteger::CompareResult::DoubleLessThanBigInt: + case Crypto::UnsignedBigInteger::CompareResult::DoubleLessThanBigInt: return builder.put_string("LessThan"sv); - case Crypto::SignedBigInteger::CompareResult::DoubleGreaterThanBigInt: + case Crypto::UnsignedBigInteger::CompareResult::DoubleGreaterThanBigInt: return builder.put_string("GreaterThan"sv); default: return builder.put_string("???"sv); diff --git a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp index 9a178410328..4b42bdc5423 100644 --- a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp +++ b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp @@ -351,153 +351,31 @@ bool SignedBigInteger::operator>=(SignedBigInteger const& other) const return !(*this < other); } -SignedBigInteger::CompareResult SignedBigInteger::compare_to_double(double value) const +UnsignedBigInteger::CompareResult SignedBigInteger::compare_to_double(double value) const { - VERIFY(!isnan(value)); - - if (isinf(value)) { - bool is_positive_infinity = __builtin_isinf_sign(value) > 0; - return is_positive_infinity ? CompareResult::DoubleGreaterThanBigInt : CompareResult::DoubleLessThanBigInt; - } - bool bigint_is_negative = m_sign; bool value_is_negative = value < 0; if (value_is_negative != bigint_is_negative) - return bigint_is_negative ? CompareResult::DoubleGreaterThanBigInt : CompareResult::DoubleLessThanBigInt; + return bigint_is_negative ? UnsignedBigInteger::CompareResult::DoubleGreaterThanBigInt : UnsignedBigInteger::CompareResult::DoubleLessThanBigInt; - // Value is zero, and from above the signs must be the same. - if (value == 0.0) { - VERIFY(!value_is_negative && !bigint_is_negative); - // Either we are also zero or value is certainly less than us. - return is_zero() ? CompareResult::DoubleEqualsBigInt : CompareResult::DoubleLessThanBigInt; + // Now both bigint and value have the same sign, so let's compare our magnitudes. + auto magnitudes_compare_result = m_unsigned_data.compare_to_double(fabs(value)); + + // If our mangnitudes are euqal, then we're equal. + if (magnitudes_compare_result == UnsignedBigInteger::CompareResult::DoubleEqualsBigInt) + return UnsignedBigInteger::CompareResult::DoubleEqualsBigInt; + + // If we're negative, revert the comparison result, otherwise return the same result. + if (value_is_negative) { + if (magnitudes_compare_result == UnsignedBigInteger::CompareResult::DoubleLessThanBigInt) + return UnsignedBigInteger::CompareResult::DoubleGreaterThanBigInt; + else + return UnsignedBigInteger::CompareResult::DoubleLessThanBigInt; + } else { + return magnitudes_compare_result; } - - // If value is not zero but we are, then since the signs are the same value must be greater. - if (is_zero()) - return CompareResult::DoubleGreaterThanBigInt; - - constexpr u64 mantissa_size = 52; - constexpr u64 exponent_size = 11; - constexpr auto exponent_bias = (1 << (exponent_size - 1)) - 1; - union FloatExtractor { - struct { - unsigned long long mantissa : mantissa_size; - unsigned exponent : exponent_size; - unsigned sign : 1; - }; - double d; - } extractor; - - extractor.d = value; - VERIFY(extractor.exponent != (1 << exponent_size) - 1); - // Exponent cannot be filled as than we must be NaN or infinity. - - i32 real_exponent = extractor.exponent - exponent_bias; - if (real_exponent < 0) { - // |value| is less than 1, and we cannot be zero so if we are negative - // value must be greater and vice versa. - return bigint_is_negative ? CompareResult::DoubleGreaterThanBigInt : CompareResult::DoubleLessThanBigInt; - } - - u64 bigint_bits_needed = m_unsigned_data.one_based_index_of_highest_set_bit(); - VERIFY(bigint_bits_needed > 0); - - // Double value is `-1^sign (1.mantissa) * 2^(exponent - bias)` so we need - // `exponent - bias + 1` bit to represent doubles value, - // for example `exponent - bias` = 3, sign = 0 and mantissa = 0 we get - // `-1^0 * 2^3 * 1 = 8` which needs 4 bits to store 8 (0b1000). - u32 double_bits_needed = real_exponent + 1; - - if (bigint_bits_needed > double_bits_needed) { - // If we need more bits to represent us, we must be of greater magnitude - // this means that if we are negative we are below value and if positive above value. - return bigint_is_negative ? CompareResult::DoubleGreaterThanBigInt : CompareResult::DoubleLessThanBigInt; - } - - if (bigint_bits_needed < double_bits_needed) - return bigint_is_negative ? CompareResult::DoubleLessThanBigInt : CompareResult::DoubleGreaterThanBigInt; - - u64 mantissa_bits = extractor.mantissa; - - // We add the bit which represents the 1. of the double value calculation - constexpr u64 mantissa_extended_bit = 1ull << mantissa_size; - - mantissa_bits |= mantissa_extended_bit; - - // Now we shift value to the left virtually, with `exponent - bias` steps - // we then pretend both it and the big int are extended with virtual zeros. - using Word = UnsignedBigInteger::Word; - auto next_bigint_word = (UnsignedBigInteger::BITS_IN_WORD - 1 + bigint_bits_needed) / UnsignedBigInteger::BITS_IN_WORD; - - VERIFY(next_bigint_word + 1 == trimmed_length()); - - auto msb_in_top_word_index = (bigint_bits_needed - 1) % UnsignedBigInteger::BITS_IN_WORD; - VERIFY(msb_in_top_word_index == (UnsignedBigInteger::BITS_IN_WORD - count_leading_zeroes(words()[next_bigint_word - 1]) - 1)); - - // We will keep the bits which are still valid in the mantissa at the top of mantissa bits. - mantissa_bits <<= 64 - (mantissa_size + 1); - - auto bits_left_in_mantissa = mantissa_size + 1; - - auto get_next_value_bits = [&](size_t num_bits) -> Word { - VERIFY(num_bits < 63); - VERIFY(bits_left_in_mantissa > 0); - if (num_bits > bits_left_in_mantissa) - num_bits = bits_left_in_mantissa; - - bits_left_in_mantissa -= num_bits; - - u64 extracted_bits = mantissa_bits & (((1ull << num_bits) - 1) << (64 - num_bits)); - // Now shift the bits down to put the most significant bit on the num_bits position - // this means the rest will be "virtual" zeros. - extracted_bits >>= 32; - - // Now shift away the used bits and fit the result into a Word. - mantissa_bits <<= num_bits; - - VERIFY(extracted_bits <= NumericLimits::max()); - return static_cast(extracted_bits); - }; - - auto bits_in_next_bigint_word = msb_in_top_word_index + 1; - - while (next_bigint_word > 0 && bits_left_in_mantissa > 0) { - Word bigint_word = words()[next_bigint_word - 1]; - Word double_word = get_next_value_bits(bits_in_next_bigint_word); - - // For the first bit we have to align it with the top bit of bigint - // and for all the other cases bits_in_next_bigint_word is 32 so this does nothing. - double_word >>= 32 - bits_in_next_bigint_word; - - if (bigint_word < double_word) - return value_is_negative ? CompareResult::DoubleLessThanBigInt : CompareResult::DoubleGreaterThanBigInt; - - if (bigint_word > double_word) - return value_is_negative ? CompareResult::DoubleGreaterThanBigInt : CompareResult::DoubleLessThanBigInt; - - --next_bigint_word; - bits_in_next_bigint_word = UnsignedBigInteger::BITS_IN_WORD; - } - - // If there are still bits left in bigint than any non zero bit means it has greater magnitude. - if (next_bigint_word > 0) { - VERIFY(bits_left_in_mantissa == 0); - while (next_bigint_word > 0) { - if (words()[next_bigint_word - 1] != 0) - return value_is_negative ? CompareResult::DoubleGreaterThanBigInt : CompareResult::DoubleLessThanBigInt; - --next_bigint_word; - } - } else if (bits_left_in_mantissa > 0) { - VERIFY(next_bigint_word == 0); - // Similarly if there are still any bits set in the mantissa it has greater magnitude. - if (mantissa_bits != 0) - return value_is_negative ? CompareResult::DoubleLessThanBigInt : CompareResult::DoubleGreaterThanBigInt; - } - - // Otherwise if both don't have bits left or the rest of the bits are zero they are equal. - return CompareResult::DoubleEqualsBigInt; } } diff --git a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h index a9adba2fd03..66666adfb51 100644 --- a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h +++ b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h @@ -140,13 +140,7 @@ public: [[nodiscard]] bool operator<(UnsignedBigInteger const& other) const; [[nodiscard]] bool operator>(UnsignedBigInteger const& other) const; - enum class CompareResult { - DoubleEqualsBigInt, - DoubleLessThanBigInt, - DoubleGreaterThanBigInt - }; - - [[nodiscard]] CompareResult compare_to_double(double) const; + [[nodiscard]] UnsignedBigInteger::CompareResult compare_to_double(double) const; private: void ensure_sign_is_valid() diff --git a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp index cefcf6e796f..6c8e7a4e691 100644 --- a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp +++ b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp @@ -602,6 +602,151 @@ bool UnsignedBigInteger::operator>=(UnsignedBigInteger const& other) const return *this > other || *this == other; } +UnsignedBigInteger::CompareResult UnsignedBigInteger::compare_to_double(double value) const +{ + VERIFY(!isnan(value)); + + if (isinf(value)) { + bool is_positive_infinity = __builtin_isinf_sign(value) > 0; + return is_positive_infinity ? CompareResult::DoubleGreaterThanBigInt : CompareResult::DoubleLessThanBigInt; + } + + bool value_is_negative = value < 0; + + if (value_is_negative) + return CompareResult::DoubleLessThanBigInt; + + // Value is zero. + if (value == 0.0) { + VERIFY(!value_is_negative); + // Either we are also zero or value is certainly less than us. + return is_zero() ? CompareResult::DoubleEqualsBigInt : CompareResult::DoubleLessThanBigInt; + } + + // If value is not zero but we are, value must be greater. + if (is_zero()) + return CompareResult::DoubleGreaterThanBigInt; + + constexpr u64 mantissa_size = 52; + constexpr u64 exponent_size = 11; + constexpr auto exponent_bias = (1 << (exponent_size - 1)) - 1; + union FloatExtractor { + struct { + unsigned long long mantissa : mantissa_size; + unsigned exponent : exponent_size; + unsigned sign : 1; + }; + double d; + } extractor; + + extractor.d = value; + // Value cannot be negative at this point. + VERIFY(extractor.sign == 0); + // Exponent cannot be all set, as then we must be NaN or infinity. + VERIFY(extractor.exponent != (1 << exponent_size) - 1); + + i32 real_exponent = extractor.exponent - exponent_bias; + if (real_exponent < 0) { + // value is less than 1, and we cannot be zero so value must be less. + return CompareResult::DoubleLessThanBigInt; + } + + u64 bigint_bits_needed = one_based_index_of_highest_set_bit(); + VERIFY(bigint_bits_needed > 0); + + // Double value is `-1^sign (1.mantissa) * 2^(exponent - bias)` so we need + // `exponent - bias + 1` bit to represent doubles value, + // for example `exponent - bias` = 3, sign = 0 and mantissa = 0 we get + // `-1^0 * 2^3 * 1 = 8` which needs 4 bits to store 8 (0b1000). + u32 double_bits_needed = real_exponent + 1; + + // If we need more bits to represent us, we must be of greater value. + if (bigint_bits_needed > double_bits_needed) + return CompareResult::DoubleLessThanBigInt; + // If we need less bits to represent us, we must be of less value. + if (bigint_bits_needed < double_bits_needed) + return CompareResult::DoubleGreaterThanBigInt; + + u64 mantissa_bits = extractor.mantissa; + + // We add the bit which represents the 1. of the double value calculation. + constexpr u64 mantissa_extended_bit = 1ull << mantissa_size; + + mantissa_bits |= mantissa_extended_bit; + + // Now we shift value to the left virtually, with `exponent - bias` steps + // we then pretend both it and the big int are extended with virtual zeros. + auto next_bigint_word = (BITS_IN_WORD - 1 + bigint_bits_needed) / BITS_IN_WORD; + + VERIFY(next_bigint_word == trimmed_length()); + + auto msb_in_top_word_index = (bigint_bits_needed - 1) % BITS_IN_WORD; + VERIFY(msb_in_top_word_index == (BITS_IN_WORD - count_leading_zeroes(words()[next_bigint_word - 1]) - 1)); + + // We will keep the bits which are still valid in the mantissa at the top of mantissa bits. + mantissa_bits <<= 64 - (mantissa_size + 1); + + auto bits_left_in_mantissa = mantissa_size + 1; + + auto get_next_value_bits = [&](size_t num_bits) -> Word { + VERIFY(num_bits < 63); + VERIFY(bits_left_in_mantissa > 0); + if (num_bits > bits_left_in_mantissa) + num_bits = bits_left_in_mantissa; + + bits_left_in_mantissa -= num_bits; + + u64 extracted_bits = mantissa_bits & (((1ull << num_bits) - 1) << (64 - num_bits)); + // Now shift the bits down to put the most significant bit on the num_bits position + // this means the rest will be "virtual" zeros. + extracted_bits >>= 32; + + // Now shift away the used bits and fit the result into a Word. + mantissa_bits <<= num_bits; + + VERIFY(extracted_bits <= NumericLimits::max()); + return static_cast(extracted_bits); + }; + + auto bits_in_next_bigint_word = msb_in_top_word_index + 1; + + while (next_bigint_word > 0 && bits_left_in_mantissa > 0) { + Word bigint_word = words()[next_bigint_word - 1]; + Word double_word = get_next_value_bits(bits_in_next_bigint_word); + + // For the first bit we have to align it with the top bit of bigint + // and for all the other cases bits_in_next_bigint_word is 32 so this does nothing. + double_word >>= 32 - bits_in_next_bigint_word; + + if (bigint_word < double_word) + return CompareResult::DoubleGreaterThanBigInt; + + if (bigint_word > double_word) + return CompareResult::DoubleLessThanBigInt; + + --next_bigint_word; + bits_in_next_bigint_word = BITS_IN_WORD; + } + + // If there are still bits left in bigint than any non zero bit means it has greater value. + if (next_bigint_word > 0) { + VERIFY(bits_left_in_mantissa == 0); + while (next_bigint_word > 0) { + if (words()[next_bigint_word - 1] != 0) + return CompareResult::DoubleLessThanBigInt; + --next_bigint_word; + } + } else if (bits_left_in_mantissa > 0) { + VERIFY(next_bigint_word == 0); + // Similarly if there are still any bits set in the mantissa it has greater value. + if (mantissa_bits != 0) + return CompareResult::DoubleGreaterThanBigInt; + } + + // Otherwise if both don't have bits left or the rest of the bits are zero they are equal. + return CompareResult::DoubleEqualsBigInt; +} + } ErrorOr AK::Formatter::format(FormatBuilder& fmtbuilder, Crypto::UnsignedBigInteger const& value) diff --git a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h index aebf6c19a40..4a7161aba9d 100644 --- a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h +++ b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h @@ -121,6 +121,14 @@ public: [[nodiscard]] bool operator>(UnsignedBigInteger const& other) const; [[nodiscard]] bool operator>=(UnsignedBigInteger const& other) const; + enum class CompareResult { + DoubleEqualsBigInt, + DoubleLessThanBigInt, + DoubleGreaterThanBigInt + }; + + [[nodiscard]] CompareResult compare_to_double(double) const; + private: friend class UnsignedBigIntegerAlgorithms; // Little endian diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp index 7d84ba0c32b..f93ee686d36 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp @@ -557,7 +557,7 @@ ThrowCompletionOr nanoseconds_to_days(VM& vm, Crypto::S // 23. If abs(nanoseconds) ≥ abs(dayLengthNs), throw a RangeError exception. auto nanoseconds_absolute = nanoseconds.is_negative() ? nanoseconds.negated_value() : nanoseconds; auto compare_result = nanoseconds_absolute.compare_to_double(fabs(day_length_ns.to_double())); - if (compare_result == Crypto::SignedBigInteger::CompareResult::DoubleLessThanBigInt || compare_result == Crypto::SignedBigInteger::CompareResult::DoubleEqualsBigInt) + if (compare_result == Crypto::UnsignedBigInteger::CompareResult::DoubleLessThanBigInt || compare_result == Crypto::UnsignedBigInteger::CompareResult::DoubleEqualsBigInt) return vm.throw_completion(ErrorType::TemporalNanosecondsConvertedToRemainderOfNanosecondsLongerThanDayLength); // 24. Return the Record { [[Days]]: days, [[Nanoseconds]]: nanoseconds, [[DayLength]]: abs(dayLengthNs) }. diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 9ea8b4f4aa2..dfee82f916a 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -1536,7 +1536,7 @@ ThrowCompletionOr is_loosely_equal(VM& vm, Value lhs, Value rhs) auto& number_side = lhs.is_number() ? lhs : rhs; auto& bigint_side = lhs.is_number() ? rhs : lhs; - return bigint_side.as_bigint().big_integer().compare_to_double(number_side.as_double()) == Crypto::SignedBigInteger::CompareResult::DoubleEqualsBigInt; + return bigint_side.as_bigint().big_integer().compare_to_double(number_side.as_double()) == Crypto::UnsignedBigInteger::CompareResult::DoubleEqualsBigInt; } // 14. Return false. @@ -1635,10 +1635,10 @@ ThrowCompletionOr is_less_than(VM& vm, Value lhs, Value rhs, bool left VERIFY(!x_numeric.is_nan() && !y_numeric.is_nan()); if (x_numeric.is_number()) { x_lower_than_y = y_numeric.as_bigint().big_integer().compare_to_double(x_numeric.as_double()) - == Crypto::SignedBigInteger::CompareResult::DoubleLessThanBigInt; + == Crypto::UnsignedBigInteger::CompareResult::DoubleLessThanBigInt; } else { x_lower_than_y = x_numeric.as_bigint().big_integer().compare_to_double(y_numeric.as_double()) - == Crypto::SignedBigInteger::CompareResult::DoubleGreaterThanBigInt; + == Crypto::UnsignedBigInteger::CompareResult::DoubleGreaterThanBigInt; } if (x_lower_than_y) return TriState::True;