mirror of
https://github.com/RGBCube/serenity
synced 2025-06-20 18:12:06 +00:00
LibJS: Correctly handle NaN and negative infinity in Math.atan2
The current implementation was missing an early return on a NaN argument and mixed up a couple of the positive/negative infinity early returns.
This commit is contained in:
parent
57a52094d1
commit
e2fb7943f7
1 changed files with 55 additions and 35 deletions
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||||
* Copyright (c) 2020, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2020, Linus Groh <linusg@serenityos.org>
|
||||||
|
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -420,44 +421,63 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::cbrt)
|
||||||
|
|
||||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::atan2)
|
JS_DEFINE_NATIVE_FUNCTION(MathObject::atan2)
|
||||||
{
|
{
|
||||||
auto y = vm.argument(0).to_number(global_object), x = vm.argument(1).to_number(global_object);
|
auto constexpr three_quarters_pi = M_PI_4 + M_PI_2;
|
||||||
auto pi_4 = M_PI_2 / 2;
|
|
||||||
auto three_pi_4 = pi_4 + M_PI_2;
|
auto y = vm.argument(0).to_number(global_object);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
auto x = vm.argument(1).to_number(global_object);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
if (x.is_positive_zero()) {
|
|
||||||
if (y.is_positive_zero() || y.is_negative_zero())
|
|
||||||
return y;
|
|
||||||
else
|
|
||||||
return (y.as_double() > 0) ? Value(M_PI_2) : Value(-M_PI_2);
|
|
||||||
}
|
|
||||||
if (x.is_negative_zero()) {
|
|
||||||
if (y.is_positive_zero())
|
|
||||||
return Value(M_PI);
|
|
||||||
else if (y.is_negative_zero())
|
|
||||||
return Value(-M_PI);
|
|
||||||
else
|
|
||||||
return (y.as_double() > 0) ? Value(M_PI_2) : Value(-M_PI_2);
|
|
||||||
}
|
|
||||||
if (x.is_positive_infinity()) {
|
|
||||||
if (y.is_infinity())
|
|
||||||
return (y.is_positive_infinity()) ? Value(pi_4) : Value(-pi_4);
|
|
||||||
else
|
|
||||||
return (y.as_double() > 0) ? Value(+0.0) : Value(-0.0);
|
|
||||||
}
|
|
||||||
if (x.is_negative_infinity()) {
|
|
||||||
if (y.is_infinity())
|
|
||||||
return (y.is_positive_infinity()) ? Value(three_pi_4) : Value(-three_pi_4);
|
|
||||||
else
|
|
||||||
return (y.as_double() > 0) ? Value(M_PI) : Value(-M_PI);
|
|
||||||
}
|
|
||||||
if (y.is_infinity())
|
|
||||||
return (y.is_positive_infinity()) ? Value(M_PI_2) : Value(-M_PI_2);
|
|
||||||
if (y.is_positive_zero())
|
|
||||||
return (x.as_double() > 0) ? Value(+0.0) : Value(M_PI);
|
|
||||||
if (y.is_negative_zero())
|
|
||||||
return (x.as_double() > 0) ? Value(-0.0) : Value(-M_PI);
|
|
||||||
|
|
||||||
|
if (y.is_nan() || x.is_nan())
|
||||||
|
return js_nan();
|
||||||
|
if (y.is_positive_infinity()) {
|
||||||
|
if (x.is_positive_infinity())
|
||||||
|
return Value(M_PI_4);
|
||||||
|
else if (x.is_negative_infinity())
|
||||||
|
return Value(three_quarters_pi);
|
||||||
|
else
|
||||||
|
return Value(M_PI_2);
|
||||||
|
}
|
||||||
|
if (y.is_negative_infinity()) {
|
||||||
|
if (x.is_positive_infinity())
|
||||||
|
return Value(-M_PI_4);
|
||||||
|
else if (x.is_negative_infinity())
|
||||||
|
return Value(-three_quarters_pi);
|
||||||
|
else
|
||||||
|
return Value(-M_PI_2);
|
||||||
|
}
|
||||||
|
if (y.is_positive_zero()) {
|
||||||
|
if (x.as_double() > 0 || x.is_positive_zero())
|
||||||
|
return Value(0.0);
|
||||||
|
else
|
||||||
|
return Value(M_PI);
|
||||||
|
}
|
||||||
|
if (y.is_negative_zero()) {
|
||||||
|
if (x.as_double() > 0 || x.is_positive_zero())
|
||||||
|
return Value(-0.0);
|
||||||
|
else
|
||||||
|
return Value(-M_PI);
|
||||||
|
}
|
||||||
|
VERIFY(y.is_finite_number() && !y.is_positive_zero() && !y.is_negative_zero());
|
||||||
|
if (y.as_double() > 0) {
|
||||||
|
if (x.is_positive_infinity())
|
||||||
|
return Value(0);
|
||||||
|
else if (x.is_negative_infinity())
|
||||||
|
return Value(M_PI);
|
||||||
|
else if (x.is_positive_zero() || x.is_negative_zero())
|
||||||
|
return Value(M_PI_2);
|
||||||
|
}
|
||||||
|
if (y.as_double() < 0) {
|
||||||
|
if (x.is_positive_infinity())
|
||||||
|
return Value(-0.0);
|
||||||
|
else if (x.is_negative_infinity())
|
||||||
|
return Value(-M_PI);
|
||||||
|
else if (x.is_positive_zero() || x.is_negative_zero())
|
||||||
|
return Value(-M_PI_2);
|
||||||
|
}
|
||||||
|
VERIFY(x.is_finite_number() && !x.is_positive_zero() && !x.is_negative_zero());
|
||||||
return Value(::atan2(y.as_double(), x.as_double()));
|
return Value(::atan2(y.as_double(), x.as_double()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue