Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // 4th-order sine approximation, in 64-bit Q17 -> Q16
- const double MY_PI = 3.141592653589793238463;
- typedef int64_t Angl;
- int64_t engineer_math_sin(Angl input)
- {
- // A sine approximation via a fourth-order cosine approx.
- // @param x angle (with 2^17 units/circle)
- // @return Sine value (Q16)
- int64_t c, x, x2, y;
- static const int64_t
- qB = 64,
- qN = 15,
- qA = 16,
- qP = 24,
- B = (2<<qP) - int64_t((1<<(qP-2)) * MY_PI), // (2 - pi/4)<<24
- C = (1<<qP) - int64_t((1<<(qP-2)) * MY_PI); // (1 - pi/4)<<24
- x = input;
- c = x << (qB-2 - qN); // Semi-circle info into carry. 60, 62, 62
- x -= 1 << qN; // cosine -> sine calc
- x = x << (qB-1 - qN); // Mask with PI
- x = x >> (qB-1 - qN); // Note: SIGNED shift! (to qN)
- x2 = x * x >> (2*qN - qP); // x=x^2 To Q24
- y = B - (x2 * C >> qP); // B - x^2*C
- y = (1 << qA) - (x2*y >> (2*qP-qA)); // A - x^2*(B-x^2*C)
- return c >= 0 ? y : -y;
- }
- void test_sine()
- {
- auto sine = engineer_math_sin;
- struct { Angl a; int64_t check, result; } tests[] = {
- {-4<<14, 0<<16 }, // sin(-pi*1) = 0
- {-3<<14, -(1<<16)/sqrt(2) }, // sin(-pi*3/4) = -1/sqrt(2)
- {-2<<14, -(1<<16) }, // sin(-pi*2/4) = -1
- {-1<<14, -(1<<16)/sqrt(2) }, // sin(-pi*1/4) = -1/sqrt(2)
- { 0<<14, (0<<16) }, // sin(0) = 0
- { 1<<14, (1<<16)/sqrt(2) }, // sin(pi*1/4) = 1/sqrt(2)
- { 2<<14, 1<<16 }, // sin(pi*2/4) = 1
- { 3<<14, (1<<16)/sqrt(2) }, // sin(pi*3/4) = 1/sqrt(2)
- { 4<<14, 0<<16 }, // sin(pi*1) = 0
- { 5<<14, -(1<<16)/sqrt(2) }, // sin(pi*5/4) = -1/sqrt(2)
- { 6<<14, -(1<<16) }, // sin(pi*5/4) = -1/sqrt(2)
- { 7<<14, -(1<<16)/sqrt(2) }, // sin(pi*5/4) = -1/sqrt(2)
- { 8<<14, (0<<16) }, // sin(pi*5/4) = -1/sqrt(2)
- };
- for (auto& test : tests)
- {
- test.result = sine(test.a);
- }
- int a = 0; // break here
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement