maths/fast: actually account for symmetries in sin
This commit is contained in:
parent
5cedd22d7a
commit
e1f864cd88
@ -21,9 +21,11 @@ namespace cruft::maths::fast {
|
||||
return std::fma (b, t, a) + std::fma (d, t, c) * t2;
|
||||
}
|
||||
|
||||
// approximates sin over the range [0; pi/4] using a polynomial.
|
||||
// approximates sin over the range [-2pi, 2pi] using a polynomial
|
||||
// approximation over [0; pi/4]
|
||||
//
|
||||
// the relative error should be on the order of 1e-6.
|
||||
// the absolute error should be maximally around 1e-5
|
||||
//
|
||||
// sollya:
|
||||
// display=hexadecimal;
|
||||
@ -38,15 +40,21 @@ namespace cruft::maths::fast {
|
||||
constexpr float
|
||||
sin (float x) noexcept
|
||||
{
|
||||
CHECK_LT (x, 2 * pi<float>);
|
||||
CHECK_GT (x, -2 * pi<float>);
|
||||
CHECK_LE (x, 2 * pi<float>);
|
||||
CHECK_GE (x, -2 * pi<float>);
|
||||
|
||||
// flip negative angles due to having an even function
|
||||
float neg = x < 0 ? x *= -1, -1 : 1;
|
||||
// Push values into the range [0, 2pi]
|
||||
if (x < 0)
|
||||
x += 2 * pi<float>;
|
||||
|
||||
// reduce the angle due to the period
|
||||
int periods = static_cast<int> (x / 2 / pi<float>);
|
||||
x -= periods * 2 * pi<float>;
|
||||
// Values in the range [pi, 2pi] are the negation of [0, pi]
|
||||
float neg = x > pi<float> ? -1 : 1;
|
||||
if (x > pi<float>)
|
||||
x -= pi<float>;
|
||||
|
||||
// Values in [0,pi] are symmetric about pi/2
|
||||
if (x > pi<float> / 2)
|
||||
x = pi<float> - x;
|
||||
|
||||
// 1,3,5,7: 1, -0x1.555546p-3f, 0x1.11077ap-7f, -0x1.9954e8p-13f;
|
||||
// 1,3,5,7,9: 1, -0x1.555556p-3f, 0x1.11115cp-7f, -0x1.a0403ap-13f, 0x1.75dc26p-19f;
|
||||
|
Loading…
Reference in New Issue
Block a user