diff options
author | Oleg Sikorskiy <olegsik@gmail.com> | 2021-03-22 21:26:16 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-03-23 08:22:15 +0100 |
commit | a1014d25def3e0eedec45a35218af63d449fa0b6 (patch) | |
tree | 32b1a1207439bd32ae2231b7bdd20824b7b588e8 /Userland/Libraries/LibJS/Runtime/Value.h | |
parent | e99dabc729f998d04fcd759528c8799df6fff4d4 (diff) | |
download | serenity-a1014d25def3e0eedec45a35218af63d449fa0b6.zip |
LibJS: Simplify positive/negative zero checks
Because both zeroes have unique and distinct bit representations,
we can bit_cast value to u64 and check if it's one of them.
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/Value.h')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Value.h | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index 81ea3298cb..fcd40cd226 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -27,6 +27,7 @@ #pragma once #include <AK/Assertions.h> +#include <AK/BitCast.h> #include <AK/Format.h> #include <AK/Forward.h> #include <AK/String.h> @@ -38,6 +39,8 @@ static constexpr double MAX_ARRAY_LIKE_INDEX = 9007199254740991.0; // 2 ** 32 - 1 static constexpr double MAX_U32 = 4294967295.0; +// Unique bit representation of negative zero (only sign bit set) +static constexpr u64 NEGATIVE_ZERO_BITS = ((u64)1 << 63); namespace JS { @@ -85,8 +88,8 @@ public: bool is_infinity() const { return is_number() && __builtin_isinf(as_double()); } bool is_positive_infinity() const { return is_number() && __builtin_isinf_sign(as_double()) > 0; } bool is_negative_infinity() const { return is_number() && __builtin_isinf_sign(as_double()) < 0; } - bool is_positive_zero() const { return is_number() && 1.0 / as_double() == INFINITY; } - bool is_negative_zero() const { return is_number() && 1.0 / as_double() == -INFINITY; } + bool is_positive_zero() const { return is_number() && bit_cast<u64>(as_double()) == 0; } + bool is_negative_zero() const { return is_number() && bit_cast<u64>(as_double()) == NEGATIVE_ZERO_BITS; } bool is_integer() const { return is_finite_number() && (i32)as_double() == as_double(); } bool is_finite_number() const { @@ -109,7 +112,7 @@ public: explicit Value(double value) { - bool is_negative_zero = value == 0.0 && (1.0 / value == -INFINITY); + bool is_negative_zero = bit_cast<u64>(value) == NEGATIVE_ZERO_BITS; if (value >= NumericLimits<i32>::min() && value <= NumericLimits<i32>::max() && trunc(value) == value && !is_negative_zero) { m_type = Type::Int32; m_value.as_i32 = static_cast<i32>(value); |