Skip to content

Instantly share code, notes, and snippets.

@dreamer
Created July 14, 2020 10:08
Show Gist options
  • Save dreamer/9742afd771b4b426529d9ad851453bee to your computer and use it in GitHub Desktop.
Save dreamer/9742afd771b4b426529d9ad851453bee to your computer and use it in GitHub Desktop.
#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;
}
#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