-
-
Save giangnguyen2412/bcab883b5a53b437b980d7be9745beaf to your computer and use it in GitHub Desktop.
#include <stdlib.h> | |
#include <stdio.h> | |
#include <math.h> | |
int compare_float(double f1, double f2) | |
{ | |
double precision = 0.00000000000000000001; | |
if ((f1 - precision) < f2) | |
{ | |
return -1; | |
} | |
else if ((f1 + precision) > f2) | |
{ | |
return 1; | |
} | |
else | |
{ | |
return 0; | |
} | |
} | |
double cos(double x){ | |
if( x < 0.0f ) | |
x = -x; | |
if (0 <= compare_float(x,M_PI_M_2)) | |
{ | |
do { | |
x -= M_PI_M_2; | |
}while(0 <= compare_float(x,M_PI_M_2)); | |
} | |
if ((0 <= compare_float(x, M_PI)) && (-1 == compare_float(x, M_PI_M_2))) | |
{ | |
x -= M_PI; | |
return ((-1)*(1.0f - (x*x/2.0f)*( 1.0f - (x*x/12.0f) * ( 1.0f - (x*x/30.0f) * (1.0f - (x*x/56.0f )*(1.0f - (x*x/90.0f)*(1.0f - (x*x/132.0f)*(1.0f - (x*x/182.0f))))))))); | |
} | |
return 1.0f - (x*x/2.0f)*( 1.0f - (x*x/12.0f) * ( 1.0f - (x*x/30.0f) * (1.0f - (x*x/56.0f )*(1.0f - (x*x/90.0f)*(1.0f - (x*x/132.0f)*(1.0f - (x*x/182.0f))))))); | |
} | |
double sin(double x){return cos(x-M_PI_2);} |
Sorry I know this is quite late but I am going to guess it might be pi/2, as cos(x) = 0; with x = n*pi/2, and since it is a periodic function, I am assuming he is just decreasing all factors of n in order for x to be between 0-1 (he turns the negative branch positives).
Sorry what is a periodic function? M_PI_M_2
reads to be a constant
#define M_PI (3.1415927f)
#define M_PI_2 (M_PI/2.0f)
#define M_PI_M_2 (M_PI*2.0f)
Thanks very nice. Was this taken from a specific libraries headers?
@Lewiscowles1986 No i wrote it myself based on Taylor's series.
@giangnguyen2412 nice to see you finally. Apologies, the question was assumed as directed at @robertdetian unless these are both your github usernames, or you have an answer with regards the defines in https://gist.github.com/giangnguyen2412/bcab883b5a53b437b980d7be9745beaf?permalink_comment_id=4286644#gistcomment-4286644
@Lewiscowles1986 Sorry for my (super) late reply. No we are not :D But I think that definition works unless you want the results more accurate (i.e. extending the numbers after the floating point).
Thanks @giangnguyen2412 for this example.
I managed to implement the float port cosine, and rewrote above code as following, which can make Taylor's series more scalable, although 7 times works well for float.
float c_cos(float x)
{
const float pi = 3.1415927;
x = std::copysign(x, 1.0f);
auto pi_count = (uint32_t)(x / pi);
x -= (float)pi_count * pi;
float taylor_series = 1.0;
for (int i = 14; i > 0; i-=2)
{
taylor_series = 1.0f - (x*x)/(float)(i*(i-1)) * taylor_series;
}
uint32_t n_one_f = 0xBF800000;
return (pi_count & 1) ? taylor_series * *(float*)&n_one_f : taylor_series;
}
What is the value and type of
M_PI_M_2
without endian-ness (literal value), and which compiler did you use to compile this?https://pubs.opengroup.org/onlinepubs/7908799/xsh/math.h.html suggests it's just
M_PI_2
and represents a double-precision of Value ofM_PI
/2Although you also use that, so could it be
M_2_PI
which is 2/M_PI