现在编译器可以优化标准C库函数sin()(由libm.so提供),将其替换为对CPU/FPU内置sin()函数的本机指令的调用,该函数作为FPU指令(FSIN for x86/x87)存在于像Core 2系列这样的新处理器上(这几乎可以追溯到i486DX)。这取决于传递给gcc编译器的优化标志。如果编译器被告知编写可以在任何i386或更新的处理器上执行的代码,它就不会进行这样的优化。-mcpu=486标志将通知编译器进行这样的优化是安全的。
#define EPSILON .0000000000001
// this is smallest effective threshold, at least on my OS (WSL ubuntu 18)
// possibly because factorial part turns 0 at some point
// and it happens faster then series element turns 0;
// validation was made against sin() from <math.h>
double ft_sin(double x)
{
int k = 2;
double r = x;
double acc = 1;
double den = 1;
double num = x;
// precision drops rapidly when x is not close to 0
// so move x to 0 as close as possible
while (x > PI)
x -= PI;
while (x < -PI)
x += PI;
if (x > PI / 2)
return (ft_sin(PI - x));
if (x < -PI / 2)
return (ft_sin(-PI - x));
// not using fabs for performance reasons
while (acc > EPSILON || acc < -EPSILON)
{
num *= -x * x;
den *= k * (k + 1);
acc = num / den;
r += acc;
k += 2;
}
return (r);
}