打印

实现math.h中的函数

[复制链接]
628|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gaoyang9992006|  楼主 | 2021-11-1 10:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*============================================================================*\
*
*                     模拟实现 math.h 库中的函数
*
*                        
*
\*============================================================================*/

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstdio>

using namespace std;

typedef int MODE;                                    // 计算sin(x)时采用弧度还是角度
const int BY_RADIDAN = 0;                           // 弧度
const int BY_ANGLE = 1;                                // 角度

const double RATIO = 0.01745329251994;                 // 角度转弧度的转换率

long Factorial( long x );                           // 阶乘
double Pow( double x, double y = 2 );               // 求x^y
double Square( double x );                          // 求平方
double Cube( double x );                            // 求立方
double Sin( double x, MODE mode = BY_RADIDAN );     // 计算sin(x)
double Cos( double x , MODE mode = BY_RADIDAN );    // 计算cos(x)
double Tan( double x , MODE mode = BY_RADIDAN );    // 计算tan(x)
int Int(double x);                                  // 取整, 不进行四舍五入
double Fabs( double x );                            // 求绝对值
double Arctanh(double x);                           // 求achtanh()
double Ln(double x);                                // 求自然对数
double Exp( double x );                             // 求e的x次幂
double Sinh( double x );                            // 求双曲正弦 sinh()
double Cosh( double x );                            // 求双曲余弦 cosh()
double Tanh(double x);                              // 求双曲正切 tanh()
double PI();                                        // 求圆周率
double gen(double x, double y);                     // 求根


// 计算阶乘
long Factorial( long x )
{
    if( 0 == x || 1 == x )
    {
        return 1;
    }

    long ans = 1;
    for( int i = 2; i <= x; i++ )
    {
        ans *= i;
    }

    return ans;
}


// 计算求幂, 默认是平方
// x^y=e^(ln(x)*y)
double Pow(double x, double y)
{
    return Exp( (Ln(x)*y) );
}

// 求根
double gen(double x, double y)
{
    return Pow(x,1/y);
}

// 计算绝对值
double Fabs( double x )
{
    if( x < -1e-9)
        return -x;
    return x;
}

int Int(double x)
{
    return static_cast<int>(Fabs( x ));
}

// 利用泰勒级数算 sin(x) , 默认传入弧度
// sinx ≈x-(x^3)/3!+(x^5)/5!-(x^7)/7!-(x^9)/9!...
// 计算精度为7位
double Sin( double x, MODE mode )
{
    // 如果是角度则转换成弧度计算
    if( BY_ANGLE ==  mode )
    {
        x *= RATIO;
    }
    x = x - Int( (x/( 2 * PI() ) ) ) * 2 * PI();
    if( 0 == x )
        return 0;

    double sum = 0, fs = x, fm = 1, t, t1 = 1;  //求和、分子、分母、精度、t1表示符号位
    int n=1;                                    //项数

    t = fs / fm;                                //精度赋值
    while( Fabs(t) >= 1e-8)                     //循环条件
    {
        sum = sum + t;                          //求和
        n++;                                    //基数增加
        fs = fs * x * x;                        //新分子
        fm = fm * ( 2*n - 2) * ( 2*n - 1 );     //新分母
        t1= -t1;                                //符号位 一正一负
        t = t1 * ( fs / fm );                   //精度
    }

    return sum;
}

// cos(x) = 1 - (x^2)/2! + (x^4)/4!......
// 结果精度为7位
double Cos( double x , MODE mode)
{
    double term,sum;
    int n = 2;

    sum = 1.0;
    term = 1.0;

    while(Fabs(term) > 1e-7)
    {
        term = term * x * x / (n * (n-1)) * (-1.0);
        sum = sum + term;
        n += 2;
    }

    return sum;
}

// tanθ = sinθ / cosθ
// 结果精度为7位
double Tan( double x , MODE mode)
{
    return ( Sin(x) / Cos(x) );
}


// 计算 x^2
double Square( double x )
{
    return ( x*x );
}

// 计算 x^3
double Cube( double x )
{
    return ( x*x*x );
}


// arctanh(x)= x + x^3/3 + x^5/5 + ...       (x≤1)
// 求sinh(y) 会用到
// 精度为7位
double Arctanh(double x)
{
    int n = 1;
    double sum = 0, term = x,  numer = x, denom = 1;
    while(Fabs(term) > 1e-8)
    {
        sum += term;                            // 求和
        numer = numer * x * x;                  // 分子
        denom = n+2;                            // 分母
        term = numer/denom;                     // 精度
        n += 2;                                 // 计数
    }

    return sum;
}


// ln(x) = 2 arctanh((x-1)/(x+1))
// 调用了Arctanh(double) 方法
double Ln(double x)
{
    return 2 * Arctanh((x-1)/(x+1));
}

// 求e^x 用于Pow( double, double )调用
// e^x = 1+x+(x^2)/2!+(x^3)/3!+...
// 精度为7位
double Exp( double x )
{
    double ret = 1, term = x, numer = x, denom = 1;;
    int n = 1;
    while(Fabs(term) > 1e-8)
    {
        ret += term;                            // 求和
        numer *= x;                             // 分子
        denom = denom * (n+1);                  // 分母
        n++;                                    // 累加
        term = numer/denom;                     // 精度
    }

    return ret;

}

// sinh(x)=(exp(x) - exp(-x)) / 2.0
// 精度为7位
double Sinh(double x)
{
    return ( ( Exp(x) - Exp(-x) ) / 2.0 );
}

// cosh(x)=(exp(x) + exp(-x)) / 2.0;
// 精度为7位
double Cosh(double x)
{
    return ( ( Exp(x) + Exp(-x) ) / 2.0 );
}

// tanh(x) = sinh(x) / cosh(x);
// 精度为7位
double Tanh(double x)
{
    return ( Sinh(x) / Cosh(x) );
}


// 求PI: pi/4 = 1 - 1/3 + 1/5 - 1/7...
double PI()
{
    int a = 3, b = 1;
    double m = 1.0, sum = 1.0;

    while( Fabs(m) > 1e-7 )
    {
        b = -b;
        m = double(b) / a;
        sum = sum + m;
        a = a + 2;
    }
    return 4 * sum;
}


//==============================================================================
void drow_line(int i = 39,string s = "━", bool newline = false)
{
    if(newline) cout << endl;
    while(i--)
        cout << s;
    cout << endl;
}

void cls()
{
    system("cls");
}

void pause()
{
    system("pause");
    //getchar();
}

// 菜单选项
void menu_option(int& menu_op,
                 int max = 14,
                 int min = 0,
                 string s = " 请选择相应的菜单选项>>> ",
                 string error = " ERROR:请选择正确的菜单选项! >>> ")
{
    cout << s;
    cin >> menu_op;
    while(cin.fail() || menu_op < min || menu_op > max)
    {
        cout << error;
        cin.clear();
        fflush(stdin);
        cin >> menu_op;
    }
}

// 选择逻辑处理
bool choos()
{
    string contin;
    while(true)
    {
        getline(cin, contin);
        if(contin == "Y" || contin == "y" || contin == "是")
        {
            return true;
        }
        else if(contin == "N" || contin == "n" || contin == "否")
        {
            return false;
        }
        else
        {
            cout << " 提示:请输入(Y/N)!>>> ";
        }
    }

}

bool check_input(int& x,
                 string str = " 请输入数据x:",
                 string err = " 输入数据格式有误!")
{
    cout << str;
    cin >> x;
    if(cin.good())
        return true;
    cout << err << endl;
    return false;
}

bool check_input(double& x,
                 string str = " 请输入数据 x:",
                 string err = " 输入数据格式有误!")
{
    cout << str;
    cin >> x;
    if(cin.good())
        return true;
        cout << err << endl;
    return false;
}

void print_result(double ans, string str )
{
    cout << str << " = " << ans << endl;
    pause();
}

//==============================================================================

/**
*
* 主菜单
*/
void menu_main()
{
    cls();
    cout << endl << endl << endl;

    cout << "\t";
    drow_line(35);

    cout << "\t\t\t\t*** 主菜单选项 ***" << endl;

    cout << "\t";
    drow_line(35);

    cout << left;
    cout << "\t        " << setw(25) << "1. 取整 Int( x )";
    cout << setw(25) << "2. 计算 sinh( x )" << endl;
    cout << "\t        " << setw(25) << "3. 计算 sin( x )";
    cout << setw(25) << "4. 计算 n^2 " << endl;
    cout << "\t        " << setw(25) << "5. 计算 n!";
    cout << setw(25) << "6. 计算 cosh( x ) " << endl;
    cout << "\t        " << setw(25) << "7. 计算 cos( x )";
    cout << setw(25) << "8. 计算 x^y" << endl;
    cout << "\t        " << setw(25) << "9. 计算 y√x ";
    cout << setw(25) << "10. 计算 tanh( x ) " << endl;
    cout << "\t        " << setw(25) << "11. 计算 Π";
    cout << setw(25) << "12. 计算 tan( x )" << endl;
    cout << "\t        " << setw(25) << "13. 计算 x^3";
    cout << setw(25) << "14. 计算 3√x" << endl;
    cout << "\t        " << setw(25) << "0. 退出系统"  << endl;

    cout << "\t";
    drow_line(35);

    cout << endl << endl;
    drow_line(39,"><");
    cout << endl;

}

int main()
{
    int ansInt;
    double ans;
    int xi;
    double x,y;

    while(true)
    {
        cls();
        menu_main();
        int option;
        menu_option(option);                            // 选择功能
        switch(option)
        {
        case 0 :
            cout << "是否退出?(Y/N)";
            if(choos())
                exit(0);
            break;
        case 1:
            check_input(x);
            ansInt = Int(x);
            drow_line(39,"**");
            cout << "Int(" << x << ") = " << ansInt << endl;
            pause();
            break;
        case 2:
            check_input(x);
            ans = Sinh(x);
            drow_line(39,"**");
            cout << "sinh(" << x << ") = " << ans << endl;
            pause();
            break;
        case 3:
            check_input(x);
            ans = Sin(x);
            drow_line(39,"**");
            cout << "sin(" << x << ") = " << ans << endl;
            pause();
            break;
        case 4:
            check_input(x);
            ans = Square(x);
            drow_line(39,"**");
            cout << x << "^2 = " << ans << endl;
            pause();
            break;
        case 5:
            check_input(xi, " 请输入整数n: ");
            ansInt = Factorial(xi);
            drow_line(39,"**");
            cout << xi << "! = " << ansInt << endl;
            pause();
            break;
        case 6:
            check_input(x);
            ans = Cosh(x);
            drow_line(39,"**");
            cout << "cosh(" << x << ") = " << ans << endl;
            pause();
            break;
        case 7:
            check_input(x);
            ans = Cos(x);
            drow_line(39,"**");
            cout << "cos(" << x << ") = " << ans << endl;
            pause();
            break;
        case 8:
            check_input(x, " 请输入数据 x y : ");
            check_input(y, "");
            ans = Pow(x,y);
            drow_line(39,"**");
            cout << x << "^" << y << " = " << ans << endl;
            pause();
            break;
        case 9:
            check_input(x, " 请输入数据 x y : ");
            check_input(y, "");
            ans = gen(x,y);
            drow_line(39,"**");
            cout << y << "√" << x << " = " << ans << endl;
            pause();
            break;
        case 10:
            check_input(x);
            ans = Tanh(x);
            drow_line(39,"**");
            cout << "tanh(" << x << ") = " << ans << endl;
            pause();
            break;
        case 11:
            ans = PI();
            drow_line(39,"**");
            cout << "π = " << ans << endl;
            pause();
            break;
        case 12:
            check_input(x);
            ans = Tan(x);
            drow_line(39,"**");
            cout << "tan(" << x << ") = " << ans << endl;
            pause();
            break;
        case 13:
            check_input(x);
            ans = Cube(x);
            drow_line(39,"**");
            cout << x << "^3 = " << ans << endl;
            pause();
            break;
        case 14:
            check_input(x);
            ans = gen(x,3);
            drow_line(39,"**");
            cout << "3√" << x << " = " << ans << endl;
            pause();
            break;
        default:
            break;
        }
    }
    return 0;
}
转自:https://www.cnblogs.com/CocoonFan/p/3164221.html

使用特权

评论回复

相关帖子

发新帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:西安公路研究院南京院
简介:主要工作从事监控网络与通信网络设计,以及从事基于嵌入式的通信与控制设备研发。擅长单片机嵌入式系统物联网设备开发,音频功放电路开发。

1954

主题

15896

帖子

207

粉丝