mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
AK: Do not use recursion in asin()
Takes asinf() from 432.0M/s to 717.6M/s in `./bench-float-exhaustive`. Takes asin() from 108.0M/s to 189.4M/s in `./ak-math-bench`. (For reference, libc++ at 259.1M/s for asinf, and macOS system libm is at 225.6M/s for asin.) No behavior change.
This commit is contained in:
1 parent
a826321e87
commit
38c474314f
1 file changed
+13
-4
+13
-4
@@ -195,17 +195,26 @@ constexpr T asin(T x)
|
||||
{
|
||||
CONSTEXPR_STATE(asin, x);
|
||||
|
||||
if (x < 0)
|
||||
return -asin(-x);
|
||||
T sign = 1;
|
||||
|
||||
// asin(x) = -asin(-x)
|
||||
// Use this to make x always >= 0.
|
||||
if (x < 0) {
|
||||
x = -x;
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
if (x > 1)
|
||||
return NaN<T>;
|
||||
|
||||
T offset = 0;
|
||||
if (x > (T)0.5) {
|
||||
// asin(x) = pi/2 - 2 * asin(sqrt((1 - x) / 2))
|
||||
// If 0.5 < x <= 1, then sqrt((1 - x) / 2 ) < 0.5,
|
||||
// and the recursion will go down the `<= 0.5` branch.
|
||||
return Pi<T> / 2 - 2 * asin(sqrt((1 - x) / 2));
|
||||
offset = sign * Pi<T> / 2;
|
||||
x = sqrt((1 - x) / 2);
|
||||
sign = sign * -2;
|
||||
}
|
||||
|
||||
// https://github.com/samhocevar/lolremez/wiki/Tutorial-4-of-5%3A-fixing-lower-order-parameters
|
||||
@@ -238,7 +247,7 @@ constexpr T asin(T x)
|
||||
}
|
||||
};
|
||||
T x2 = x * x;
|
||||
return (x + x * x2 * f(x2));
|
||||
return offset + sign * (x + x * x2 * f(x2));
|
||||
}
|
||||
|
||||
template<FloatingPoint T>
|
||||
|
||||
Reference in new issue
Block a user