三角函数优化:sin(x),使用Taylor 级数
time(&t1);
double tm2, tm3, tm5, tm7;
tm2 = val* val;
tm3 = tm2 *val;
tm5 = tm2 * tm3;
tm7 = tm2 * tm5;
for(int i = 0; i < 300000000; i++)
{
result_good = 0.99999748720576542294 * val- 0.16665168104891719958* tm3+ 0.0083095169821075058614* tm5 - 0.00018447221849405965569*tm7;
}
time(&t2);
printf("%-7s:%5g seconds (%d bytes)\n", "short", difftime(t2, t1), sizeof(long)); //3000000000次 8 秒
</pre></p><p></p><pre class="html" name="code" snippet_file_name="blog_20141204_4_3406833" code_snippet_id="542417"><strong>三角函数优化:sin(x),使用多项式展开</strong>
<strong>三角函数未优化:sin(x)</strong>
time(&t1);
for (int i =0; i < 300000000; i++)
{
result_ori = sin(val);
}
time(&t2);
printf("%-7s:%5g seconds (%d bytes)\n", "short", difftime(t2, t1), sizeof(long)); //3000000000次73秒
<strong>下面再贴两个三角函数优化算法</strong>
<pre class="html" name="code">#define ONE_PI (3.14159265)
#define TWO_PI (2.0 * 3.14159265)
#define ANGLE_UNIT (TWO_PI/10.0)
double mx_sin(double rad)
{
double sine;
if (rad < 0)
sine = rad*(1.27323954 + 0.405284735 * rad);
else
sine = rad * (1.27323954 - 0.405284735 * rad);
if (sine < 0)
sine = sine*(-0.225 * (sine + 1) + 1);
else
sine = sine * (0.225 *( sine - 1) + 1);
return sine;
}
double my_sin(double rad)
{
char flag = 1;
if (rad >= ONE_PI)
{
rad -= ONE_PI;
flag = -1;
}
return mx_sin(rad) * flag;
}
float my_cos(double rad)
{
char flag = 1;
rad += ONE_PI/2.0;
if (rad >= ONE_PI)
{
flag = -1;
rad -= ONE_PI;
}
return my_sin(rad)*flag;
}
cos(x)函数优化, 使用Taylor 级数
cosx=0.9995795170399418561−0.49639233850557584748x2+
0.037209332130166132557x4
cosx=0.99999528272039384102−0.49993092003443151405x2+
0.041511736836071483348x4−0.0012787139913533120562x6
cosx=0.99999996727291751153−0.49999926901995966899x2+
0.041664091445612914943x4−0.0013857422438193591537x6+2.3237659272108738645×10−5x8
cosx=0.99999999985553855719−0.49999999531049355017x2+
0.041666642521451954795x4−0.0013888439838802731086x6+2.4764124863984253×10−5x8−2.6120941216892450088×10−7x10
开平方算法优化(牛顿迭代法)计算参数x的平方根的倒数
float InvSqrt (float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f3759df - (i >> 1); // 计算第一个近似根
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x); // 牛顿迭代法
return x;
}//这里倒数第二行代码可以迭代几次会更精确,我执行了5次,可以精确到小数点后6位。//InvSqrt 3000000000次14秒
float my_sqrt(float number)
{
long i;
float x, y;
const float f = 1.5F;
x = number * 0.5F;
y = number;
i = * ( long * ) &y;
i = 0x5f3759df - ( i >> 1 );
y = * ( float * ) &i;
y = y * ( f - ( x * y * y ) );
y = y * ( f - ( x * y * y ) );
return number * y; //300000000次16秒
}
sqrt((double)88); //系统函数300000000次3秒,说明上面的算法优化后速度反而变慢。