zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    动态可配置表单的设计构思
    mysql之视图
    mysql学习之数据备份和恢复
    mysqli操作
    mysql登录出现1045错误修改方法
    mysql之简单的多表查询
    sql优化的方法总结
    mysql语句操作
    linux 批量替换文件内容
    zend framework 数据库操作(DB操作)总结
  • 原文地址:https://www.cnblogs.com/nsnow/p/1795351.html
Copyright © 2011-2022 走看看