mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:48:10 +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, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -420,44 +421,63 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::cbrt)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::atan2)
|
||||
{
|
||||
auto y = vm.argument(0).to_number(global_object), x = vm.argument(1).to_number(global_object);
|
||||
auto pi_4 = M_PI_2 / 2;
|
||||
auto three_pi_4 = pi_4 + M_PI_2;
|
||||
auto constexpr three_quarters_pi = M_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())
|
||||
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()));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue