Explorar o código

LibJS: Add support for Math.ceil() and Math.trunc()

Introduce support for the both of these Math methods.
Math.trunc is implemented in terms of Math.ceil or Math.floor
based on the input value. Added tests as well.
Brian Gianforcaro %!s(int64=5) %!d(string=hai) anos
pai
achega
240a5b5fd7

+ 27 - 0
Libraries/LibJS/Runtime/MathObject.cpp

@@ -38,8 +38,10 @@ MathObject::MathObject()
     put_native_function("random", random);
     put_native_function("sqrt", sqrt, 1);
     put_native_function("floor", floor, 1);
+    put_native_function("ceil", ceil, 1);
     put_native_function("round", round, 1);
     put_native_function("max", max, 2);
+    put_native_function("trunc", trunc, 1);
 
     put("E", Value(M_E));
     put("LN2", Value(M_LN2));
@@ -98,6 +100,17 @@ Value MathObject::floor(Interpreter& interpreter)
     return Value(::floor(number.as_double()));
 }
 
+Value MathObject::ceil(Interpreter& interpreter)
+{
+    if (!interpreter.argument_count())
+        return js_nan();
+
+    auto number = interpreter.argument(0).to_number();
+    if (number.is_nan())
+        return js_nan();
+    return Value(::ceil(number.as_double()));
+}
+
 Value MathObject::round(Interpreter& interpreter)
 {
     if (!interpreter.argument_count())
@@ -127,4 +140,18 @@ Value MathObject::max(Interpreter& interpreter)
     }
 }
 
+Value MathObject::trunc(Interpreter& interpreter)
+{
+    if (!interpreter.argument_count())
+        return js_nan();
+
+    auto number = interpreter.argument(0).to_number();
+    if (number.is_nan())
+        return js_nan();
+
+    if (number.as_double() < 0)
+        return MathObject::ceil(interpreter);
+    return MathObject::floor(interpreter);
+}
+
 }

+ 2 - 0
Libraries/LibJS/Runtime/MathObject.h

@@ -42,8 +42,10 @@ private:
     static Value random(Interpreter&);
     static Value sqrt(Interpreter&);
     static Value floor(Interpreter&);
+    static Value ceil(Interpreter&);
     static Value round(Interpreter&);
     static Value max(Interpreter&);
+    static Value trunc(Interpreter&);
 };
 
 }

+ 19 - 0
Libraries/LibJS/Tests/Math.ceil.js

@@ -0,0 +1,19 @@
+function assert(x) { if (!x) throw 1; }
+
+try {
+    assert(Math.ceil(0.95) === 1);
+    assert(Math.ceil(4) === 4);
+    assert(Math.ceil(7.004) == 8);
+    assert(Math.ceil(-0.95) === -0);
+    assert(Math.ceil(-4)    === -4);
+    assert(Math.ceil(-7.004) === -7);
+
+    assert(isNaN(Math.ceil()));
+    assert(isNaN(Math.ceil(NaN)));
+
+    assert(Math.ceil.length === 1);
+
+    console.log("PASS");
+} catch (e) {
+    console.log("FAIL: " + e);
+}

+ 18 - 0
Libraries/LibJS/Tests/Math.trunc.js

@@ -0,0 +1,18 @@
+function assert(x) { if (!x) throw 1; }
+
+try {
+    assert(Math.trunc(13.37) === 13);
+    assert(Math.trunc(42.84) === 42);
+    assert(Math.trunc(0.123) ===  0);
+    assert(Math.trunc(-0.123) === -0);
+
+    assert(isNaN(Math.trunc(NaN)));
+    assert(isNaN(Math.trunc('foo')));
+    assert(isNaN(Math.trunc()));
+
+    assert(Math.trunc.length === 1);
+
+    console.log("PASS");
+} catch (e) {
+    console.log("FAIL: " + e);
+}