Created
July 14, 2020 10:08
-
-
Save dreamer/5f7626c1f73983f5a250120aac67a9a1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cmath> | |
#include <cstdint> | |
#include <cstdio> | |
// uncomment the one to use: | |
// | |
#define bhaskar | |
//#define taylor | |
//#define stdf | |
//#define stdd | |
#ifdef stdf | |
#warning "using sinf/cosf" | |
#define coarse_sin sinf | |
#define coarse_cos cosf | |
#endif | |
#ifdef stdd | |
#warning "using sin/cos" | |
#define coarse_sin sin | |
#define coarse_cos cos | |
#endif | |
#ifdef bhaskar | |
#warning "bhaskar" | |
// extremely fast sine and cosine approximations good to roughly four digits | |
// of accuracy (suitable for 16-bit audio calculations). | |
// Credit: Bhaskara I (c. 600 – c. 680) sine approximation formula | |
constexpr float coarse_sin(float rad) | |
{ | |
constexpr auto pi_f = static_cast<float>(M_PI); | |
rad /= 2 * pi_f; | |
rad -= static_cast<int>(rad); | |
if (rad <= 0.5f) { | |
const float t = 2 * rad * (2 * rad - 1); | |
return (pi_f * t) / ((pi_f - 4) * t - 1); | |
} else { | |
const float t = 2 * (1 - rad) * (1 - 2 * rad); | |
return -(pi_f * t) / ((pi_f - 4) * t - 1); | |
} | |
} | |
constexpr float coarse_cos(float rad) | |
{ | |
constexpr auto pi_f = static_cast<float>(M_PI); | |
return coarse_sin(rad + 0.5f * pi_f); | |
} | |
#endif | |
#ifdef taylor | |
#warning "taylor" | |
constexpr float coarse_sin(float x) | |
{ | |
constexpr int fact_3 = 1 * 2 * 3; | |
constexpr int fact_5 = fact_3 * 4 * 5; | |
constexpr int fact_7 = fact_5 * 6 * 7; | |
const float x_pow_2 = x * x; | |
const float x_pow_3 = x_pow_2 * x; | |
const float x_pow_5 = x_pow_3 * x_pow_2; | |
const float x_pow_7 = x_pow_5 * x_pow_2; | |
const float taylor_1 = x - (x_pow_3 / fact_3); | |
const float taylor_2 = taylor_1 + (x_pow_5 / fact_5); | |
const float taylor_3 = taylor_2 - (x_pow_7 / fact_7); | |
return taylor_3; | |
} | |
constexpr float coarse_cos(float x) | |
{ | |
constexpr auto pi_f = static_cast<float>(M_PI); | |
return coarse_sin(x + 0.5f * pi_f); | |
} | |
#endif | |
#define ROUNDS 100000000 | |
int main(int argc, char**argv) | |
{ | |
uint32_t round = ROUNDS + argc; | |
const float step = 1.0 / ROUNDS; | |
float angle = 0; | |
double sum = 0; | |
while (round--) { | |
sum += coarse_cos(angle) + coarse_sin(angle); | |
angle += step; | |
} | |
printf("sum over %d round is %f\n", ROUNDS, sum); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment