mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-05 01:10:24 +00:00
LibJS: Handle negativity in Temporal's ApplyUnsignedRoundingMode
I don't fully understand the BigInt math here, as the computation for d1 and d2 don't align with the spec due to BigInt logic. This was discussed a bit in SerenityOS's Discord some years ago: https://discord.com/channels/830522505605283862/851522357734408232/978786665306918932 But some new tests in test262 indicate that we need to handle negative values here, instead of just throwing away the sign.
This commit is contained in:
Notes:
github-actions[bot]
2025-11-14 11:33:50 +00:00
Author: https://github.com/trflynn89 Commit: https://github.com/LadybirdBrowser/ladybird/commit/c7e4a99219d Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6812
@@ -947,10 +947,11 @@ Crypto::SignedBigInteger apply_unsigned_rounding_mode(Crypto::SignedDivisionResu
|
||||
return r2;
|
||||
|
||||
// 6. Let d1 be x – r1.
|
||||
auto d1 = x.remainder.unsigned_value();
|
||||
auto const& d1 = x.remainder;
|
||||
|
||||
// 7. Let d2 be r2 – x.
|
||||
auto d2 = MUST(increment.minus(x.remainder.unsigned_value()));
|
||||
auto d2 = x.remainder.is_negative() ? x.remainder.plus(increment) : x.remainder.minus(increment);
|
||||
d2.negate();
|
||||
|
||||
// 8. If d1 < d2, return r1.
|
||||
if (d1 < d2)
|
||||
|
||||
@@ -52,6 +52,22 @@ describe("correct behavior", () => {
|
||||
expect(instant.toString(options)).toBe(expected);
|
||||
}
|
||||
});
|
||||
|
||||
test("rounding", () => {
|
||||
const instant = new Temporal.Instant(-999999999999999990n);
|
||||
const roundedDown = "1938-04-24T22:13:20.000Z";
|
||||
const roundedUp = "1938-04-24T22:13:20.001Z";
|
||||
|
||||
for (const roundingMode of ["halfCeil", "halfFloor", "halfExpand", "halfTrunc", "halfEven", "floor", "trunc"]) {
|
||||
const options = { smallestUnit: "millisecond", roundingMode };
|
||||
expect(instant.toString(options)).toBe(roundedDown);
|
||||
}
|
||||
|
||||
for (const roundingMode of ["ceil", "expand"]) {
|
||||
const options = { smallestUnit: "millisecond", roundingMode };
|
||||
expect(instant.toString(options)).toBe(roundedUp);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("errors", () => {
|
||||
|
||||
Reference in New Issue
Block a user