sin cos exp 是用泰勒公式和麥克勞林公式來計算。為防止冪運算指數過高,在計算較大輸入參數的時候容易導致溢出,考慮到sin和cos都是以2*PI為周期的,所以在函數內設定一個閥值(可自 行修改,此處使用2*PI作為閥值),當實參大於閥值的時候,將其計算到-2*PI~2*PI象限,既防止了大數溢出問題,又提高了運算速度。另外,誤差範圍也可自行控制。sqrt的計算是採用一個逼近演算法,此處設定了一個數組,作為逼近演算法的起始基值。exp的計算因子存在一個大數溢出的問題,此處採用步數來限制無窮次計算,步數值為經驗值,不能全面計算該函數的所有值。//mathtest.c
#include "stdio.h"
#include "math.h"#define PI 3.14156
float sinx(float x);
float fun_sinx(float x, int m);
float expx(float x);
float fun_exp(float x,int n);
float sqrtx(float t);
float cosx(float x);
float fun_cos(float x, int m);
int main()
{
float x = PI/2;
printf("sin(%f)=%f\n",x,sin(x));
printf("sinx(%f)=%f\n",x,sinx(x));
printf("cos(%f)=%f\n",x,cos(x));
printf("cosx(%f)=%f\n",x,cosx(x));
x = PI/1.3;
printf("sin(%f)=%f\n",x,sin(x));
printf("sinx(%f)=%f\n",x,sinx(x));
printf("cos(%f)=%f\n",x,cos(x));
printf("cosx(%f)=%f\n",x,cosx(x));
x = PI/2.3;
printf("sin(%f)=%f\n",x,sin(x));
printf("sinx(%f)=%f\n",x,sinx(x));
printf("cos(%f)=%f\n",x,cos(x));
printf("cosx(%f)=%f\n",x,cosx(x));
x = PI/0.3;
printf("sin(%f)=%f\n",x,sin(x));
printf("sinx(%f)=%f\n",x,sinx(x));
printf("cos(%f)=%f\n",x,cos(x));
printf("cosx(%f)=%f\n",x,cosx(x));
x = 4.5*PI;
printf("sin(%f)=%f\n",x,sin(x));
printf("sinx(%f)=%f\n",x,sinx(x));
printf("cos(%f)=%f\n",x,cos(x));
printf("cosx(%f)=%f\n",x,cosx(x));
x = 1999;
printf("sin(%f)=%f\n",x,sin(x));
printf("sinx(%f)=%f\n",x,sinx(x));
printf("cos(%f)=%f\n",x,cos(x));
printf("cosx(%f)=%f\n",x,cosx(x));
x = 1.0;
printf("exp(%f) = %f\n",x,exp(x));
printf("expx(%f) = %f\n",x,expx(x));x = 2.0;
printf("exp(%f) = %f\n",x,exp(x));
printf("expx(%f) = %f\n",x,expx(x));x= .0014;
printf("sqrt(%f) = %f\n",x,sqrt(x));
printf("sqrtx(%f) = %f\n",x,sqrtx(x));
printf("hello, math!\n");
return 0;
} float sinx(float x)
{
int m = 1;
float tempRet;
float retVal = 0.0;float Pi = 3.1415926;if (x > 2*Pi || x < -2*Pi)
{
x -=((int)(x/(2*Pi)))*(2*Pi);
}do
{
tempRet = fun_sinx(x,m);
retVal += tempRet;
m++;
} while (tempRet<-.0000005||tempRet>0.0000005);return retVal;
}float fun_sinx(float x, int m)
{
float ret = 0.0;
int i = 0;if (m%2 == 0)
{
ret = -1.0;
}else
{
ret = 1.0;
}for (i=1;i<=2*m-1;i++)
{
ret = ret * x/i;
}
return ret;
}float expx(float x)
{
float retVal = 1.0;
float tempRet;
int n = 1;int step;if(x>10) step = 20;else step = 40;do
{
tempRet = fun_exp(x,n);
retVal += tempRet;
n++;
} while ((tempRet<-0.0000005||tempRet>0.0000005)&&(n<step));return retVal;
}float fun_exp(float x,int n)
{
float ret = 1.0;
int i = 0;for (i=1;i<=n;i++)
{
ret = ret*x/i;
}return ret;
}
float sqrt_array[] ={0.0,1.0,4.0,3.0*3.0,4.0*4.0,5.0*5.0,6.0*6.0,7.0*7.0,8.0*8.0,9.0*9.0,10.0*10.0,100.0*100.0,1000.0*1000.0};
float sqrtx(float t)
{
float sqrt_base =1.0;
int i = 0;
float sqrt_ret;
float temp;while(i<=12&&t>sqrt_array[i++]) ;//遍曆尋找一個基的範圍if (i>=1&&i<=11)//0.0 < t < 100.0*100.0
{
sqrt_base *= (i-1.0);
}
else if (i==12)
{
sqrt_base = 100.0;
}else if (i==13)
{
sqrt_base = 1000.0;
} sqrt_ret = sqrt_base;
temp = (sqrt_ret * sqrt_ret - t)/t;while (temp>0.00005 || temp < -0.00005)
{
sqrt_ret = (sqrt_base + t/sqrt_base)/2.0;
sqrt_base = sqrt_ret;
temp = (sqrt_ret * sqrt_ret - t)/t;
}
return sqrt_ret;
}
float fun_cos(float x, int m)
{
float ret_val;
int i;if (m%2 == 0)
{
ret_val = 1.0;
}else
{
ret_val = -1.0;
}for (i=1;i<=2*m;i++)
{
ret_val = ret_val * x/i;
}return ret_val;
}float cosx(float x)
{
float ret_val = 1.0;
float temp_ret;
int m = 1;
float Pi = 3.1415926;if (x > 2*Pi || x < -2*Pi)
{
x = x-((int)(x/(2*Pi)))*(2*Pi);
}do
{
temp_ret = fun_cos(x,m++);
ret_val += temp_ret;} while (temp_ret>0.00005 || temp_ret<-0.00005);return ret_val;
}
from:http://blog.edu.cn/user1/12168/archives/2007/1921714.shtml