diff options
author | Brian Gianforcaro <b.gianfo@gmail.com> | 2020-04-05 01:32:04 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-05 10:38:13 +0200 |
commit | b8cef3a2d3657cc3e244e98f9c3b7457528558ef (patch) | |
tree | e01bab584cb49c125f267a3215818983ef2d2510 /Libraries/LibJS | |
parent | 41bfff1abe995a4a590ea23fa741cf46381b0a94 (diff) | |
download | serenity-b8cef3a2d3657cc3e244e98f9c3b7457528558ef.zip |
LibJS: Add support for floating point modulous
This change implements floating point mod based on the algorithm
used in LibM's fmod() implementation. To avoid taking a dependency
on LibM from LibJS I reimplemented the formula in LibJS.
I've incuded some of the example MDM test cases as well.
This surfaced and issue handling NaN which I've fixed as well.
Diffstat (limited to 'Libraries/LibJS')
-rw-r--r-- | Libraries/LibJS/Runtime/Value.cpp | 10 | ||||
-rw-r--r-- | Libraries/LibJS/Tests/modulo-basic.js | 14 |
2 files changed, 22 insertions, 2 deletions
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); |