-
Notifications
You must be signed in to change notification settings - Fork 23
/
badmath.hh
38 lines (37 loc) · 1.15 KB
/
badmath.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* Internal header for implementing "fast" sin(x*pi).
*/
#include <cmath>
namespace badmath {
// what are you gonna do about it? x can't be too big!
// this is supposed to turn into FMA where fast, and not invoke the fma() libc function otherwise.
// like how Julia's muladd() works, but at the mercy of the compiler.
template<typename T>
inline T red4(T x) {
return -4 * std::nearbyint(x * 0.25) + x;
}
// devmaster user "Nick"'s approximation formula
// https://web.archive.org/web/20171228230531/http://forum.devmaster.net/t/fast-and-accurate-sine-cosine/9648
template<typename T>
inline T sinpi_nick(T x) {
x = red4(x * 2); // = 0 to 2pi; nick-magic works on units of 0.5pi
T y = x * (2 - std::abs(x));
return y * (0.775 + 0.225 * std::abs(y));
}
template<typename T>
inline T sinpi_std(T x) {
return std::sin(x * M_PI);
}
template<typename T>
inline T sinpi(T x) {
#ifndef PRCOORDS_NO_BADMATH
return sinpi_nick(x);
#else
return sinpi_std(x);
#endif
}
template<typename T>
inline T cospi(T x) {
return sinpi(x + 0.5);
}
}