实现math.h中的函数

[复制链接]
858|0
 楼主| gaoyang9992006 发表于 2021-11-1 10:17 | 显示全部楼层 |阅读模式
  1. /*============================================================================*\
  2. *
  3. *                     模拟实现 math.h 库中的函数
  4. *
  5. *                        
  6. *
  7. \*============================================================================*/

  8. #include <iostream>
  9. #include <iomanip>
  10. #include <string>
  11. #include <cstdlib>
  12. #include <cstdio>

  13. using namespace std;

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

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

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


  35. // 计算阶乘
  36. long Factorial( long x )
  37. {
  38.     if( 0 == x || 1 == x )
  39.     {
  40.         return 1;
  41.     }

  42.     long ans = 1;
  43.     for( int i = 2; i <= x; i++ )
  44.     {
  45.         ans *= i;
  46.     }

  47.     return ans;
  48. }


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

  55. // 求根
  56. double gen(double x, double y)
  57. {
  58.     return Pow(x,1/y);
  59. }

  60. // 计算绝对值
  61. double Fabs( double x )
  62. {
  63.     if( x < -1e-9)
  64.         return -x;
  65.     return x;
  66. }

  67. int Int(double x)
  68. {
  69.     return static_cast<int>(Fabs( x ));
  70. }

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

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

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

  96.     return sum;
  97. }

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

  104.     sum = 1.0;
  105.     term = 1.0;

  106.     while(Fabs(term) > 1e-7)
  107.     {
  108.         term = term * x * x / (n * (n-1)) * (-1.0);
  109.         sum = sum + term;
  110.         n += 2;
  111.     }

  112.     return sum;
  113. }

  114. // tanθ = sinθ / cosθ
  115. // 结果精度为7位
  116. double Tan( double x , MODE mode)
  117. {
  118.     return ( Sin(x) / Cos(x) );
  119. }


  120. // 计算 x^2
  121. double Square( double x )
  122. {
  123.     return ( x*x );
  124. }

  125. // 计算 x^3
  126. double Cube( double x )
  127. {
  128.     return ( x*x*x );
  129. }


  130. // arctanh(x)= x + x^3/3 + x^5/5 + ...       (x≤1)
  131. // 求sinh(y) 会用到
  132. // 精度为7位
  133. double Arctanh(double x)
  134. {
  135.     int n = 1;
  136.     double sum = 0, term = x,  numer = x, denom = 1;
  137.     while(Fabs(term) > 1e-8)
  138.     {
  139.         sum += term;                            // 求和
  140.         numer = numer * x * x;                  // 分子
  141.         denom = n+2;                            // 分母
  142.         term = numer/denom;                     // 精度
  143.         n += 2;                                 // 计数
  144.     }

  145.     return sum;
  146. }


  147. // ln(x) = 2 arctanh((x-1)/(x+1))
  148. // 调用了Arctanh(double) 方法
  149. double Ln(double x)
  150. {
  151.     return 2 * Arctanh((x-1)/(x+1));
  152. }

  153. // 求e^x 用于Pow( double, double )调用
  154. // e^x = 1+x+(x^2)/2!+(x^3)/3!+...
  155. // 精度为7位
  156. double Exp( double x )
  157. {
  158.     double ret = 1, term = x, numer = x, denom = 1;;
  159.     int n = 1;
  160.     while(Fabs(term) > 1e-8)
  161.     {
  162.         ret += term;                            // 求和
  163.         numer *= x;                             // 分子
  164.         denom = denom * (n+1);                  // 分母
  165.         n++;                                    // 累加
  166.         term = numer/denom;                     // 精度
  167.     }

  168.     return ret;

  169. }

  170. // sinh(x)=(exp(x) - exp(-x)) / 2.0
  171. // 精度为7位
  172. double Sinh(double x)
  173. {
  174.     return ( ( Exp(x) - Exp(-x) ) / 2.0 );
  175. }

  176. // cosh(x)=(exp(x) + exp(-x)) / 2.0;
  177. // 精度为7位
  178. double Cosh(double x)
  179. {
  180.     return ( ( Exp(x) + Exp(-x) ) / 2.0 );
  181. }

  182. // tanh(x) = sinh(x) / cosh(x);
  183. // 精度为7位
  184. double Tanh(double x)
  185. {
  186.     return ( Sinh(x) / Cosh(x) );
  187. }


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

  193.     while( Fabs(m) > 1e-7 )
  194.     {
  195.         b = -b;
  196.         m = double(b) / a;
  197.         sum = sum + m;
  198.         a = a + 2;
  199.     }
  200.     return 4 * sum;
  201. }


  202. //==============================================================================
  203. void drow_line(int i = 39,string s = "━", bool newline = false)
  204. {
  205.     if(newline) cout << endl;
  206.     while(i--)
  207.         cout << s;
  208.     cout << endl;
  209. }

  210. void cls()
  211. {
  212.     system("cls");
  213. }

  214. void pause()
  215. {
  216.     system("pause");
  217.     //getchar();
  218. }

  219. // 菜单选项
  220. void menu_option(int& menu_op,
  221.                  int max = 14,
  222.                  int min = 0,
  223.                  string s = " 请选择相应的菜单选项>>> ",
  224.                  string error = " ERROR:请选择正确的菜单选项! >>> ")
  225. {
  226.     cout << s;
  227.     cin >> menu_op;
  228.     while(cin.fail() || menu_op < min || menu_op > max)
  229.     {
  230.         cout << error;
  231.         cin.clear();
  232.         fflush(stdin);
  233.         cin >> menu_op;
  234.     }
  235. }

  236. // 选择逻辑处理
  237. bool choos()
  238. {
  239.     string contin;
  240.     while(true)
  241.     {
  242.         getline(cin, contin);
  243.         if(contin == "Y" || contin == "y" || contin == "是")
  244.         {
  245.             return true;
  246.         }
  247.         else if(contin == "N" || contin == "n" || contin == "否")
  248.         {
  249.             return false;
  250.         }
  251.         else
  252.         {
  253.             cout << " 提示:请输入(Y/N)!>>> ";
  254.         }
  255.     }

  256. }

  257. bool check_input(int& x,
  258.                  string str = " 请输入数据x:",
  259.                  string err = " 输入数据格式有误!")
  260. {
  261.     cout << str;
  262.     cin >> x;
  263.     if(cin.good())
  264.         return true;
  265.     cout << err << endl;
  266.     return false;
  267. }

  268. bool check_input(double& x,
  269.                  string str = " 请输入数据 x:",
  270.                  string err = " 输入数据格式有误!")
  271. {
  272.     cout << str;
  273.     cin >> x;
  274.     if(cin.good())
  275.         return true;
  276.         cout << err << endl;
  277.     return false;
  278. }

  279. void print_result(double ans, string str )
  280. {
  281.     cout << str << " = " << ans << endl;
  282.     pause();
  283. }

  284. //==============================================================================

  285. /**
  286. *
  287. * 主菜单
  288. */
  289. void menu_main()
  290. {
  291.     cls();
  292.     cout << endl << endl << endl;

  293.     cout << "\t";
  294.     drow_line(35);

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

  296.     cout << "\t";
  297.     drow_line(35);

  298.     cout << left;
  299.     cout << "\t        " << setw(25) << "1. 取整 Int( x )";
  300.     cout << setw(25) << "2. 计算 sinh( x )" << endl;
  301.     cout << "\t        " << setw(25) << "3. 计算 sin( x )";
  302.     cout << setw(25) << "4. 计算 n^2 " << endl;
  303.     cout << "\t        " << setw(25) << "5. 计算 n!";
  304.     cout << setw(25) << "6. 计算 cosh( x ) " << endl;
  305.     cout << "\t        " << setw(25) << "7. 计算 cos( x )";
  306.     cout << setw(25) << "8. 计算 x^y" << endl;
  307.     cout << "\t        " << setw(25) << "9. 计算 y√x ";
  308.     cout << setw(25) << "10. 计算 tanh( x ) " << endl;
  309.     cout << "\t        " << setw(25) << "11. 计算 Π";
  310.     cout << setw(25) << "12. 计算 tan( x )" << endl;
  311.     cout << "\t        " << setw(25) << "13. 计算 x^3";
  312.     cout << setw(25) << "14. 计算 3√x" << endl;
  313.     cout << "\t        " << setw(25) << "0. 退出系统"  << endl;

  314.     cout << "\t";
  315.     drow_line(35);

  316.     cout << endl << endl;
  317.     drow_line(39,"><");
  318.     cout << endl;

  319. }

  320. int main()
  321. {
  322.     int ansInt;
  323.     double ans;
  324.     int xi;
  325.     double x,y;

  326.     while(true)
  327.     {
  328.         cls();
  329.         menu_main();
  330.         int option;
  331.         menu_option(option);                            // 选择功能
  332.         switch(option)
  333.         {
  334.         case 0 :
  335.             cout << "是否退出?(Y/N)";
  336.             if(choos())
  337.                 exit(0);
  338.             break;
  339.         case 1:
  340.             check_input(x);
  341.             ansInt = Int(x);
  342.             drow_line(39,"**");
  343.             cout << "Int(" << x << ") = " << ansInt << endl;
  344.             pause();
  345.             break;
  346.         case 2:
  347.             check_input(x);
  348.             ans = Sinh(x);
  349.             drow_line(39,"**");
  350.             cout << "sinh(" << x << ") = " << ans << endl;
  351.             pause();
  352.             break;
  353.         case 3:
  354.             check_input(x);
  355.             ans = Sin(x);
  356.             drow_line(39,"**");
  357.             cout << "sin(" << x << ") = " << ans << endl;
  358.             pause();
  359.             break;
  360.         case 4:
  361.             check_input(x);
  362.             ans = Square(x);
  363.             drow_line(39,"**");
  364.             cout << x << "^2 = " << ans << endl;
  365.             pause();
  366.             break;
  367.         case 5:
  368.             check_input(xi, " 请输入整数n: ");
  369.             ansInt = Factorial(xi);
  370.             drow_line(39,"**");
  371.             cout << xi << "! = " << ansInt << endl;
  372.             pause();
  373.             break;
  374.         case 6:
  375.             check_input(x);
  376.             ans = Cosh(x);
  377.             drow_line(39,"**");
  378.             cout << "cosh(" << x << ") = " << ans << endl;
  379.             pause();
  380.             break;
  381.         case 7:
  382.             check_input(x);
  383.             ans = Cos(x);
  384.             drow_line(39,"**");
  385.             cout << "cos(" << x << ") = " << ans << endl;
  386.             pause();
  387.             break;
  388.         case 8:
  389.             check_input(x, " 请输入数据 x y : ");
  390.             check_input(y, "");
  391.             ans = Pow(x,y);
  392.             drow_line(39,"**");
  393.             cout << x << "^" << y << " = " << ans << endl;
  394.             pause();
  395.             break;
  396.         case 9:
  397.             check_input(x, " 请输入数据 x y : ");
  398.             check_input(y, "");
  399.             ans = gen(x,y);
  400.             drow_line(39,"**");
  401.             cout << y << "√" << x << " = " << ans << endl;
  402.             pause();
  403.             break;
  404.         case 10:
  405.             check_input(x);
  406.             ans = Tanh(x);
  407.             drow_line(39,"**");
  408.             cout << "tanh(" << x << ") = " << ans << endl;
  409.             pause();
  410.             break;
  411.         case 11:
  412.             ans = PI();
  413.             drow_line(39,"**");
  414.             cout << "π = " << ans << endl;
  415.             pause();
  416.             break;
  417.         case 12:
  418.             check_input(x);
  419.             ans = Tan(x);
  420.             drow_line(39,"**");
  421.             cout << "tan(" << x << ") = " << ans << endl;
  422.             pause();
  423.             break;
  424.         case 13:
  425.             check_input(x);
  426.             ans = Cube(x);
  427.             drow_line(39,"**");
  428.             cout << x << "^3 = " << ans << endl;
  429.             pause();
  430.             break;
  431.         case 14:
  432.             check_input(x);
  433.             ans = gen(x,3);
  434.             drow_line(39,"**");
  435.             cout << "3√" << x << " = " << ans << endl;
  436.             pause();
  437.             break;
  438.         default:
  439.             break;
  440.         }
  441.     }
  442.     return 0;
  443. }
转自:https://www.cnblogs.com/CocoonFan/p/3164221.html

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2055

主题

16424

帖子

222

粉丝
快速回复 在线客服 返回列表 返回顶部