From 4813385c9ae5b2d93fb245a36f7e12d6b021c472 Mon Sep 17 00:00:00 2001 From: davidot Date: Mon, 28 Nov 2022 12:05:01 +0100 Subject: [PATCH] LibJS: Add spec comments and check for edge cases in Math.log --- .../Libraries/LibJS/Runtime/MathObject.cpp | 23 ++++++++++++++++--- .../LibJS/Tests/builtins/Math/Math.log.js | 3 +++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/MathObject.cpp b/Userland/Libraries/LibJS/Runtime/MathObject.cpp index a45e79128f6..10b757c53c5 100644 --- a/Userland/Libraries/LibJS/Runtime/MathObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/MathObject.cpp @@ -522,10 +522,27 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::imul) // 21.3.2.20 Math.log ( x ), https://tc39.es/ecma262/#sec-math.log JS_DEFINE_NATIVE_FUNCTION(MathObject::log) { - auto value = TRY(vm.argument(0).to_number(vm)).as_double(); - if (value < 0) + // 1. Let n be ? ToNumber(x). + auto number = TRY(vm.argument(0).to_number(vm)); + + // 2. If n is NaN or n is +∞𝔽, return n. + if (number.is_nan() || number.is_positive_infinity()) + return number; + + // 3. If n is 1𝔽, return +0𝔽. + if (number.as_double() == 1.) + return Value(0); + + // 4. If n is +0𝔽 or n is -0𝔽, return -∞𝔽. + if (number.is_positive_zero() || number.is_negative_zero()) + return js_negative_infinity(); + + // 5. If n < -0𝔽, return NaN. + if (number.as_double() < -0.) return js_nan(); - return Value(::log(value)); + + // 6. Return an implementation-approximated Number value representing the result of the natural logarithm of ℝ(n). + return Value(::log(number.as_double())); } // 21.3.2.23 Math.log2 ( x ), https://tc39.es/ecma262/#sec-math.log2 diff --git a/Userland/Libraries/LibJS/Tests/builtins/Math/Math.log.js b/Userland/Libraries/LibJS/Tests/builtins/Math/Math.log.js index 9b19569dce4..d5ea9d9976f 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Math/Math.log.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Math/Math.log.js @@ -5,4 +5,7 @@ test("basic functionality", () => { expect(Math.log(0)).toBe(-Infinity); expect(Math.log(1)).toBe(0); expect(Math.log(10)).toBeCloseTo(2.302585092994046); + expect(Math.log(NaN)).toBe(NaN); + expect(Math.log(Number.POSITIVE_INFINITY)).toBe(Number.POSITIVE_INFINITY); + expect(Math.log(-0.0)).toBe(Number.NEGATIVE_INFINITY); });