计算机只能算加法,那你有没有想过计算机是怎样计算象sinx这样的周期函数?
要想明白这个原理,那你必须知道泰勒公式(高等代数):
f(x) = f(x0) + f’(x0)/1!*(x-x0)1 + f’’(x0)/2!*(x-x0)2 + f’’’(x0)/3!*(x-x0)3 ……+ f(n)(x)/n!*(x-x0)n + Rn(x)
其中
Rn(x) = f(§)/(n+1)!*(x-x0)(n+1),x<§ <x0 或x0<§ <x
f’(x), f’’(x), ……f(n)(x)导数
要想证明泰勒公式,你必须先知道拉革朗日中值定理;要想知道拉革朗日中值定理,你必须知道导数;要想知道导数,你又必须知道极限。所以说要想成为未来的电脑高手,学数学是很重要的。
说回来,你要想看证明,可以去买本高数的书来看。这里不证。
特殊的,我们令x0 = 0
于是,就得到了麦克劳林公式
f(x) = f(0) + f’(0)/1!*x1 + f’’(0)/2!*x2 + f’’’(0)/3!*x3 ……+ f(n)(0)/n!*xn + Rn(x)
其中
Rn(x) = f(§)/(n+1)!*x(n+1),x<§ <x0 或x0<§ <x
f’(x), f’’(x), ……f(n)(x)导数
因为Rn(x)是xn 的高阶无穷小,所以
f(x) ≈ f(0) + f’(0)/1!*x1 + f’’(0)/2!*x2 + f’’’(0)/3!*x3 ……+ f(n)(0)/n!*xn
n值越大,精确度越高。
这样,我们就将一个复杂的函数f(x)化成了计算机能计算的多项式。
实践证明,对于sin(x), 当n=5时,sin(x)在[0, pi/2] 范围内已经很精确了。
f(0) = 0,
f’(0) = 1,
f’’(0) = 0,
f’’’(0) = -1,
f(4)(0) = 0,
f(5)(0) = 1
所以,sin(x) = x – 1/3!*x3 + 1/5!*x5 = x – 1/6*x3 + 1/120*x5
当x的值不在[0, pi/2] 范围内时,可以根据sin(x)的周期性把x转换到[0, pi/2] 范围内。
代码:
const double PI = 3.1415926;
double my_sin(double r)
{
double s = 1.0;
while(r > 2*PI)
r -= 2*PI;
while(r < 0)
r += 2*PI;
if(r<= PI/2)
{
s = 1;
}
else if(r <= PI)
{
s = 1;
r = PI - r;
}
else if(r <= PI*3/2)
{
s = -1;
r = r - PI;
}
else if(r <= 2*PI)
{
s = -1;
r = 2*PI - r;
}
else
{
return 2; // return error
}
return s*(r - (1.0/6.0)*pow(r,3) + (1.0/120.0)*pow(r,5)); //if you use pow(), you should include <cmath>
}