diff options
author | davidot <davidot@serenityos.org> | 2022-08-19 23:51:32 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-08-24 23:27:17 +0100 |
commit | cb49c07fb700884adcf4030220770855015c571e (patch) | |
tree | a1479cbb967e97bcfeadd5a516d84b891fc3ef76 /Userland/Libraries | |
parent | b5c00830c2a58d6b657a0a93c2bff29594487897 (diff) | |
download | serenity-cb49c07fb700884adcf4030220770855015c571e.zip |
LibJS: Use the new BigInt compare_to_double algorithm :^)
Although this is much more complicated it does not seem to impact
performance that much even when looking only at values in which the
previous casting to i32 was correct.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Value.cpp | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 8575e5f4fb..7e343c2618 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -1448,10 +1448,13 @@ ThrowCompletionOr<bool> is_loosely_equal(VM& vm, Value lhs, Value rhs) // b. If ℝ(x) = ℝ(y), return true; otherwise return false. if ((lhs.is_number() && !lhs.is_integral_number()) || (rhs.is_number() && !rhs.is_integral_number())) return false; - if (lhs.is_number()) - return Crypto::SignedBigInteger { MUST(lhs.to_i32(vm)) } == rhs.as_bigint().big_integer(); - else - return Crypto::SignedBigInteger { MUST(rhs.to_i32(vm)) } == lhs.as_bigint().big_integer(); + + VERIFY(!lhs.is_nan() && !rhs.is_nan()); + + 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; } // 14. Return false. @@ -1547,14 +1550,13 @@ ThrowCompletionOr<TriState> is_less_than(VM& vm, Value lhs, Value rhs, bool left VERIFY((x_numeric.is_number() && y_numeric.is_bigint()) || (x_numeric.is_bigint() && y_numeric.is_number())); bool x_lower_than_y; + VERIFY(!x_numeric.is_nan() && !y_numeric.is_nan()); if (x_numeric.is_number()) { - x_lower_than_y = x_numeric.is_integral_number() - ? Crypto::SignedBigInteger { MUST(x_numeric.to_i32(vm)) } < y_numeric.as_bigint().big_integer() - : (Crypto::SignedBigInteger { MUST(x_numeric.to_i32(vm)) } < y_numeric.as_bigint().big_integer() || Crypto::SignedBigInteger { MUST(x_numeric.to_i32(vm)) + 1 } < y_numeric.as_bigint().big_integer()); + x_lower_than_y = y_numeric.as_bigint().big_integer().compare_to_double(x_numeric.as_double()) + == Crypto::SignedBigInteger::CompareResult::DoubleLessThanBigInt; } else { - x_lower_than_y = y_numeric.is_integral_number() - ? x_numeric.as_bigint().big_integer() < Crypto::SignedBigInteger { MUST(y_numeric.to_i32(vm)) } - : (x_numeric.as_bigint().big_integer() < Crypto::SignedBigInteger { MUST(y_numeric.to_i32(vm)) } || x_numeric.as_bigint().big_integer() < Crypto::SignedBigInteger { MUST(y_numeric.to_i32(vm)) + 1 }); + x_lower_than_y = x_numeric.as_bigint().big_integer().compare_to_double(y_numeric.as_double()) + == Crypto::SignedBigInteger::CompareResult::DoubleGreaterThanBigInt; } if (x_lower_than_y) return TriState::True; |