mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibJS: Handle +Infinity, -Infinity, +0 and -0 in modulo operator
Fixes 11 test262 cases.
This commit is contained in:
parent
32825107de
commit
c20669328d
Notes:
sideshowbarker
2024-07-18 04:52:44 +09:00
Author: https://github.com/Lubrsi Commit: https://github.com/SerenityOS/serenity/commit/c20669328db Pull-request: https://github.com/SerenityOS/serenity/pull/9729 Reviewed-by: https://github.com/linusg ✅
2 changed files with 47 additions and 0 deletions
|
@ -1212,11 +1212,36 @@ Value mod(GlobalObject& global_object, Value lhs, Value rhs)
|
|||
if (vm.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric)) {
|
||||
// 6.1.6.1.6 Number::remainder ( n, d ), https://tc39.es/ecma262/#sec-numeric-types-number-remainder
|
||||
|
||||
// 1. If n is NaN or d is NaN, return NaN.
|
||||
if (lhs_numeric.is_nan() || rhs_numeric.is_nan())
|
||||
return js_nan();
|
||||
|
||||
// 2. If n is +∞𝔽 or n is -∞𝔽, return NaN.
|
||||
if (lhs_numeric.is_positive_infinity() || lhs_numeric.is_negative_infinity())
|
||||
return js_nan();
|
||||
|
||||
// 3. If d is +∞𝔽 or d is -∞𝔽, return n.
|
||||
if (rhs_numeric.is_positive_infinity() || rhs_numeric.is_negative_infinity())
|
||||
return lhs_numeric;
|
||||
|
||||
// 4. If d is +0𝔽 or d is -0𝔽, return NaN.
|
||||
if (rhs_numeric.is_positive_zero() || rhs_numeric.is_negative_zero())
|
||||
return js_nan();
|
||||
|
||||
// 5. If n is +0𝔽 or n is -0𝔽, return n.
|
||||
if (lhs_numeric.is_positive_zero() || lhs_numeric.is_negative_zero())
|
||||
return lhs_numeric;
|
||||
|
||||
// 6. Assert: n and d are finite and non-zero.
|
||||
|
||||
auto index = lhs_numeric.as_double();
|
||||
auto period = rhs_numeric.as_double();
|
||||
auto trunc = (double)(i32)(index / period);
|
||||
|
||||
// 7. Let r be ℝ(n) - (ℝ(d) × q) where q is an integer that is negative if and only if n and d have opposite sign, and whose magnitude is as large as possible without exceeding the magnitude of ℝ(n) / ℝ(d).
|
||||
// 8. Return 𝔽(r).
|
||||
return Value(index - trunc * period);
|
||||
}
|
||||
if (both_bigint(lhs_numeric, rhs_numeric)) {
|
||||
|
|
|
@ -13,4 +13,26 @@ test("basic functionality", () => {
|
|||
expect(-4 % 2).toBe(-0);
|
||||
expect(5.5 % 2).toBe(1.5);
|
||||
expect(NaN % 2).toBeNaN();
|
||||
expect(2 % NaN).toBeNaN();
|
||||
expect(NaN % NaN).toBeNaN();
|
||||
expect(Infinity % 1).toBeNaN();
|
||||
expect(-Infinity % 1).toBeNaN();
|
||||
expect(1 % Infinity).toBe(1);
|
||||
expect(1 % -Infinity).toBe(1);
|
||||
expect(1 % 0).toBeNaN();
|
||||
expect(1 % -0).toBeNaN();
|
||||
expect(0 % 5).toBe(0);
|
||||
expect(-0 % 5).toBe(-0);
|
||||
|
||||
// test262 examples
|
||||
expect(1 % null).toBeNaN();
|
||||
expect(null % 1).toBe(0);
|
||||
expect(true % null).toBeNaN();
|
||||
expect(null % true).toBe(0);
|
||||
expect("1" % null).toBeNaN();
|
||||
expect(null % "1").toBe(0);
|
||||
expect(null % undefined).toBeNaN();
|
||||
expect(undefined % null).toBeNaN();
|
||||
expect(undefined % undefined).toBeNaN();
|
||||
expect(null % null).toBeNaN();
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue