sqrt sin cos exp 函数泰勒公式和迈克劳林实现

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
原文地址:https://www.cnblogs.com/nsnow/p/1795351.html