Prechádzať zdrojové kódy

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.
Brian Gianforcaro 5 rokov pred
rodič
commit
b8cef3a2d3

+ 8 - 2
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)

+ 14 - 0
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);