mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-30 00:31:14 +00:00
LibJS: Rewrite Math.hypot to handle exceptions, NaNs, Infinity properly
The specification requires that we immediately return Infinity during the iteration over the arguments if positive or negative infinity is encountered, and return a NaN if it is encountered and no Infinity was found. The specification also requires all arguments to be coerced into numbers before the operation starts, or else a number conversion exception could be missed due to the Infinity/NaN early return.
This commit is contained in:
parent
03255c1c53
commit
57a52094d1
Notes:
sideshowbarker
2024-07-18 16:50:42 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/57a52094d1e Pull-request: https://github.com/SerenityOS/serenity/pull/7797 Reviewed-by: https://github.com/awesomekling Reviewed-by: https://github.com/linusg
|
@ -473,20 +473,33 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::fround)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::hypot)
|
||||
{
|
||||
if (!vm.argument_count())
|
||||
return Value(0);
|
||||
|
||||
auto hypot = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
hypot = Value(hypot.as_double() * hypot.as_double());
|
||||
for (size_t i = 1; i < vm.argument_count(); ++i) {
|
||||
auto cur = vm.argument(i).to_number(global_object);
|
||||
Vector<Value> coerced;
|
||||
for (size_t i = 0; i < vm.argument_count(); ++i) {
|
||||
auto number = vm.argument(i).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
hypot = Value(hypot.as_double() + cur.as_double() * cur.as_double());
|
||||
coerced.append(number);
|
||||
}
|
||||
return Value(::sqrt(hypot.as_double()));
|
||||
|
||||
for (auto& number : coerced) {
|
||||
if (number.is_positive_infinity() || number.is_negative_infinity())
|
||||
return js_infinity();
|
||||
}
|
||||
|
||||
auto only_zero = true;
|
||||
double sum_of_squares = 0;
|
||||
for (auto& number : coerced) {
|
||||
if (number.is_nan() || number.is_positive_infinity())
|
||||
return number;
|
||||
if (number.is_negative_infinity())
|
||||
return js_infinity();
|
||||
if (!number.is_positive_zero() && !number.is_negative_zero())
|
||||
only_zero = false;
|
||||
sum_of_squares += number.as_double() * number.as_double();
|
||||
}
|
||||
if (only_zero)
|
||||
return Value(0);
|
||||
return Value(::sqrt(sum_of_squares));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::imul)
|
||||
|
|
Loading…
Reference in a new issue