summaryrefslogtreecommitdiff
path: root/Libraries/LibJS
diff options
context:
space:
mode:
authorBrian Gianforcaro <b.gianfo@gmail.com>2020-04-05 01:32:04 -0700
committerAndreas Kling <kling@serenityos.org>2020-04-05 10:38:13 +0200
commitb8cef3a2d3657cc3e244e98f9c3b7457528558ef (patch)
treee01bab584cb49c125f267a3215818983ef2d2510 /Libraries/LibJS
parent41bfff1abe995a4a590ea23fa741cf46381b0a94 (diff)
downloadserenity-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.cpp10
-rw-r--r--Libraries/LibJS/Tests/modulo-basic.js14
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);