diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index 901558ecee..13687cb5b3 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -258,8 +258,14 @@ Value div(Value lhs, Value rhs) Value mod(Value lhs, Value rhs) { - // FIXME: It seems like JavaScript should allow modulo for doubles as well(?) - return Value(lhs.to_i32() % rhs.to_i32()); + if (lhs.to_number().is_nan() || rhs.to_number().is_nan()) + return js_nan(); + + double index = lhs.to_number().as_double(); + double period = rhs.to_number().as_double(); + double trunc = (double)(i32) (index / period); + + return Value(index - trunc * period); } Value typed_eq(Value lhs, Value rhs) diff --git a/Libraries/LibJS/Tests/modulo-basic.js b/Libraries/LibJS/Tests/modulo-basic.js index 78410ee6c5..1b59a73419 100644 --- a/Libraries/LibJS/Tests/modulo-basic.js +++ b/Libraries/LibJS/Tests/modulo-basic.js @@ -2,6 +2,20 @@ function assert(x) { if (!x) throw 1; } try { assert(10 % 3 === 1); + assert(10.5 % 2.5 === 0.5); + assert(-0.99 % 0.99 === -0); + + // Examples form MDN: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators + assert(12 % 5 === 2); + assert(-1 % 2 === -1); + assert(1 % -2 === 1); + assert(isNaN(NaN % 2); + assert(1 % 2 === 1); + assert(2 % 3 === 2); + assert(-4 % 2 === -0); + assert(5.5 % 2 === 1.5); + console.log("PASS"); } catch (e) { console.log("FAIL: " + e);