diff options
author | davidot <davidot@serenityos.org> | 2022-08-10 11:57:46 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-08-15 17:11:25 +0200 |
commit | da8715a07cf84b8ea81043f78327dce69b66d681 (patch) | |
tree | 6abbff985956aa4d0e4af280c8eabc8510533ef1 | |
parent | 27abbfdf093545d8c208f07aa1b9bafb14eaea93 (diff) | |
download | serenity-da8715a07cf84b8ea81043f78327dce69b66d681.zip |
LibJS: Add extreme value tests for cos and sin
These sometimes produce different NaN patterns which can mess up the
value encoding.
4 files changed, 35 insertions, 3 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/MathObject.cpp b/Userland/Libraries/LibJS/Runtime/MathObject.cpp index 1679e2f14a..b76da01547 100644 --- a/Userland/Libraries/LibJS/Runtime/MathObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/MathObject.cpp @@ -183,27 +183,53 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::trunc) // 21.3.2.30 Math.sin ( x ), https://tc39.es/ecma262/#sec-math.sin JS_DEFINE_NATIVE_FUNCTION(MathObject::sin) { + // 1. Let n be ? ToNumber(x). auto number = TRY(vm.argument(0).to_number(global_object)); - if (number.is_nan()) + // 2. If n is NaN, n is +0𝔽, or n is -0𝔽, return n. + if (number.is_nan() || number.is_positive_zero() || number.is_negative_zero()) + return number; + + // 3. If n is +∞𝔽 or n is -∞𝔽, return NaN. + if (number.is_infinity()) return js_nan(); + + // 4. Return an implementation-approximated Number value representing the result of the sine of ℝ(n). return Value(::sin(number.as_double())); } // 21.3.2.12 Math.cos ( x ), https://tc39.es/ecma262/#sec-math.cos JS_DEFINE_NATIVE_FUNCTION(MathObject::cos) { + // 1. Let n be ? ToNumber(x). auto number = TRY(vm.argument(0).to_number(global_object)); - if (number.is_nan()) + + // 2. If n is NaN, n is +∞𝔽, or n is -∞𝔽, return NaN. + if (number.is_nan() || number.is_infinity()) return js_nan(); + + // 3. If n is +0𝔽 or n is -0𝔽, return 1𝔽. + if (number.is_positive_zero() || number.is_negative_zero()) + return Value(1); + + // 4. Return an implementation-approximated Number value representing the result of the cosine of ℝ(n). return Value(::cos(number.as_double())); } // 21.3.2.33 Math.tan ( x ), https://tc39.es/ecma262/#sec-math.tan JS_DEFINE_NATIVE_FUNCTION(MathObject::tan) { + // Let n be ? ToNumber(x). auto number = TRY(vm.argument(0).to_number(global_object)); - if (number.is_nan()) + + // 2. If n is NaN, n is +0𝔽, or n is -0𝔽, return n. + if (number.is_nan() || number.is_positive_zero() || number.is_negative_zero()) + return number; + + // 3. If n is +∞𝔽, or n is -∞𝔽, return NaN. + if (number.is_infinity()) return js_nan(); + + // 4. Return an implementation-approximated Number value representing the result of the tangent of ℝ(n). return Value(::tan(number.as_double())); } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Math/Math.cos.js b/Userland/Libraries/LibJS/Tests/builtins/Math/Math.cos.js index 8186bc4199..19fa430c2d 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Math/Math.cos.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Math/Math.cos.js @@ -11,4 +11,6 @@ test("basic functionality", () => { expect(Math.cos([1, 2, 3])).toBeNaN(); expect(Math.cos({})).toBeNaN(); expect(Math.cos("foo")).toBeNaN(); + expect(Math.cos(-Infinity)).toBeNaN(); + expect(Math.cos(Infinity)).toBeNaN(); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Math/Math.sin.js b/Userland/Libraries/LibJS/Tests/builtins/Math/Math.sin.js index f5434d94c7..54d858e0c0 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Math/Math.sin.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Math/Math.sin.js @@ -12,4 +12,6 @@ test("basic functionality", () => { expect(Math.sin([1, 2, 3])).toBeNaN(); expect(Math.sin({})).toBeNaN(); expect(Math.sin("foo")).toBeNaN(); + expect(Math.sin(Infinity)).toBeNaN(); + expect(Math.sin(-Infinity)).toBeNaN(); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Math/Math.tan.js b/Userland/Libraries/LibJS/Tests/builtins/Math/Math.tan.js index ef1f32f163..beccdc28ce 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Math/Math.tan.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Math/Math.tan.js @@ -11,4 +11,6 @@ test("basic functionality", () => { expect(Math.tan([1, 2, 3])).toBeNaN(); expect(Math.tan({})).toBeNaN(); expect(Math.tan("foo")).toBeNaN(); + expect(Math.tan(Infinity)).toBeNaN(); + expect(Math.tan(-Infinity)).toBeNaN(); }); |