From 240a5b5fd702e0eacf1108138f3df85b4e1514dc Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Sun, 5 Apr 2020 01:35:50 -0700 Subject: [PATCH] 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. --- Libraries/LibJS/Runtime/MathObject.cpp | 27 ++++++++++++++++++++++++++ Libraries/LibJS/Runtime/MathObject.h | 2 ++ Libraries/LibJS/Tests/Math.ceil.js | 19 ++++++++++++++++++ Libraries/LibJS/Tests/Math.trunc.js | 18 +++++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 Libraries/LibJS/Tests/Math.ceil.js create mode 100644 Libraries/LibJS/Tests/Math.trunc.js diff --git a/Libraries/LibJS/Runtime/MathObject.cpp b/Libraries/LibJS/Runtime/MathObject.cpp index fd47c7d0cf..613f6cef8f 100644 --- a/Libraries/LibJS/Runtime/MathObject.cpp +++ b/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); +} + } diff --git a/Libraries/LibJS/Runtime/MathObject.h b/Libraries/LibJS/Runtime/MathObject.h index eaf5147966..e62e177c5f 100644 --- a/Libraries/LibJS/Runtime/MathObject.h +++ b/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&); }; } diff --git a/Libraries/LibJS/Tests/Math.ceil.js b/Libraries/LibJS/Tests/Math.ceil.js new file mode 100644 index 0000000000..a8507c5eb6 --- /dev/null +++ b/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); +} diff --git a/Libraries/LibJS/Tests/Math.trunc.js b/Libraries/LibJS/Tests/Math.trunc.js new file mode 100644 index 0000000000..29a9f1ad2a --- /dev/null +++ b/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); +}