diff options
author | Linus Groh <mail@linusgroh.de> | 2021-11-23 22:30:27 +0000 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-11-24 17:53:00 +0000 |
commit | 1e41a8668dbe61fedfb1bcd499480b6801de40b4 (patch) | |
tree | a12f98510b8402541c6337763edf1c184d3c2135 | |
parent | a20b189eabc24eeaa5ea23dee620e8111dc62e98 (diff) | |
download | serenity-1e41a8668dbe61fedfb1bcd499480b6801de40b4.zip |
LibJS: Add sign(Crypto::SignedBigInteger const&) overload
3 files changed, 18 insertions, 9 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp index eed71e054c..e518b2ab65 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp @@ -952,6 +952,20 @@ double sign(double n) return 1; } +double sign(Crypto::SignedBigInteger const& n) +{ + // 1. If n is NaN, n is +0𝔽, or n is −0𝔽, return n. + if (n == Crypto::SignedBigInteger { 0 }) + return n.is_negative() ? -0 : 0; + + // 2. If n < +0𝔽, return −1𝔽. + if (n.is_negative()) + return -1; + + // 3. Return 1𝔽. + return 1; +} + // 13.29 ConstrainToRange ( x, minimum, maximum ), https://tc39.es/proposal-temporal/#sec-temporal-constraintorange double constrain_to_range(double x, double minimum, double maximum) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h index be8d7d4b2f..8e0e17f179 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h @@ -124,6 +124,7 @@ Optional<u16> maximum_temporal_duration_rounding_increment(StringView unit); ThrowCompletionOr<void> reject_object_with_calendar_or_time_zone(GlobalObject&, Object&); String format_seconds_string_part(u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Variant<StringView, u8> const& precision); double sign(double); +double sign(Crypto::SignedBigInteger const&); double constrain_to_range(double x, double minimum, double maximum); i64 round_number_to_increment(double, u64 increment, StringView rounding_mode); BigInt* round_number_to_increment(GlobalObject&, BigInt const&, u64 increment, StringView rounding_mode); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp index 87fc1a9698..0edb131e18 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp @@ -403,13 +403,7 @@ ThrowCompletionOr<NanosecondsToDaysResult> nanoseconds_to_days(GlobalObject& glo auto nanoseconds = nanoseconds_bigint.big_integer(); // 3. Let sign be ! ℝ(Sign(𝔽(nanoseconds))). - i8 sign; - if (nanoseconds == Crypto::UnsignedBigInteger { 0 }) - sign = 0; - else if (nanoseconds.is_negative()) - sign = -1; - else - sign = 1; + auto sign = Temporal::sign(nanoseconds); // 4. Let dayLengthNs be 8.64 × 10^13. auto day_length_ns = "86400000000000"_sbigint; @@ -425,7 +419,7 @@ ThrowCompletionOr<NanosecondsToDaysResult> nanoseconds_to_days(GlobalObject& glo // a. Return the Record { [[Days]]: the integral part of nanoseconds / dayLengthNs, [[Nanoseconds]]: (abs(nanoseconds) modulo dayLengthNs) × sign, [[DayLength]]: dayLengthNs }. return NanosecondsToDaysResult { .days = nanoseconds.divided_by(day_length_ns).quotient.to_double(), - .nanoseconds = make_handle(js_bigint(vm, Crypto::SignedBigInteger { nanoseconds.unsigned_value() }.divided_by(day_length_ns).remainder.multiplied_by(Crypto::SignedBigInteger { sign }))), + .nanoseconds = make_handle(js_bigint(vm, Crypto::SignedBigInteger { nanoseconds.unsigned_value() }.divided_by(day_length_ns).remainder.multiplied_by(Crypto::SignedBigInteger { (i32)sign }))), .day_length = day_length_ns.to_double() }; } @@ -484,7 +478,7 @@ ThrowCompletionOr<NanosecondsToDaysResult> nanoseconds_to_days(GlobalObject& glo day_length_ns = one_day_farther_ns.minus(intermediate_ns); // c. If (nanoseconds − dayLengthNs) × sign ≥ 0, then - if (nanoseconds.minus(day_length_ns).multiplied_by(Crypto::SignedBigInteger { sign }) >= "0"_sbigint) { + if (nanoseconds.minus(day_length_ns).multiplied_by(Crypto::SignedBigInteger { (i32)sign }) >= "0"_sbigint) { // i. Set nanoseconds to nanoseconds − dayLengthNs. nanoseconds = nanoseconds.minus(day_length_ns); |