mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 18:17:41 +00:00
LibM: Use fptan/fpatan instead of approximating atan2/tan
The previous versions were very inaccurate, and sometimes wrong.
This commit is contained in:
parent
801daf47f0
commit
dbc5b05b7a
2 changed files with 24 additions and 7 deletions
|
@ -495,7 +495,7 @@ float tanhf(float x) NOEXCEPT
|
||||||
return (float)tanhl(x);
|
return (float)tanhl(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long double ampsin(long double angle) NOEXCEPT
|
[[maybe_unused]] static long double ampsin(long double angle) NOEXCEPT
|
||||||
{
|
{
|
||||||
long double looped_angle = fmodl(M_PI + angle, M_TAU) - M_PI;
|
long double looped_angle = fmodl(M_PI + angle, M_TAU) - M_PI;
|
||||||
long double looped_angle_squared = looped_angle * looped_angle;
|
long double looped_angle_squared = looped_angle * looped_angle;
|
||||||
|
@ -514,7 +514,13 @@ static long double ampsin(long double angle) NOEXCEPT
|
||||||
|
|
||||||
long double tanl(long double angle) NOEXCEPT
|
long double tanl(long double angle) NOEXCEPT
|
||||||
{
|
{
|
||||||
return ampsin(angle) / ampsin(M_PI_2 + angle);
|
long double ret = 0.0, one;
|
||||||
|
__asm__(
|
||||||
|
"fptan"
|
||||||
|
: "=t"(one), "=u"(ret)
|
||||||
|
: "0"(angle));
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
double tan(double angle) NOEXCEPT
|
double tan(double angle) NOEXCEPT
|
||||||
|
@ -721,8 +727,6 @@ float coshf(float x) NOEXCEPT
|
||||||
|
|
||||||
long double atan2l(long double y, long double x) NOEXCEPT
|
long double atan2l(long double y, long double x) NOEXCEPT
|
||||||
{
|
{
|
||||||
if (x > 0)
|
|
||||||
return atanl(y / x);
|
|
||||||
if (x == 0) {
|
if (x == 0) {
|
||||||
if (y > 0)
|
if (y > 0)
|
||||||
return M_PI_2;
|
return M_PI_2;
|
||||||
|
@ -730,9 +734,13 @@ long double atan2l(long double y, long double x) NOEXCEPT
|
||||||
return -M_PI_2;
|
return -M_PI_2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (y >= 0)
|
|
||||||
return atanl(y / x) + M_PI;
|
long double result = 0; //atanl(y / x);
|
||||||
return atanl(y / x) - M_PI;
|
__asm__("fpatan"
|
||||||
|
: "=t"(result)
|
||||||
|
: "0"(x), "u"(y)
|
||||||
|
: "st(1)");
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
double atan2(double y, double x) NOEXCEPT
|
double atan2(double y, double x) NOEXCEPT
|
||||||
|
|
|
@ -29,6 +29,15 @@
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
TEST_CASE(atan2)
|
||||||
|
{
|
||||||
|
EXPECT_APPROXIMATE(atan2(-1, -0.0e0), -M_PI_2);
|
||||||
|
EXPECT_APPROXIMATE(atan2(-0.0e0, -1), -M_PI);
|
||||||
|
EXPECT_APPROXIMATE(atan2(0.0e0, -1), M_PI);
|
||||||
|
EXPECT_APPROXIMATE(atan2(-0.0e0, 1), -0.0e0);
|
||||||
|
EXPECT_APPROXIMATE(atan2(0.0e0, 1), 0.0e0);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE(trig)
|
TEST_CASE(trig)
|
||||||
{
|
{
|
||||||
EXPECT_APPROXIMATE(sin(1234), 0.601927);
|
EXPECT_APPROXIMATE(sin(1234), 0.601927);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue