之前一直都很迷惑pow()函数时怎么实现的,对于整数次的幂我还能很容易做到,但是对于分数次幂就不是那么好做了。需要一些高等数学级数的知识。

  我这里实现了求ln(x), pow(double x, double y), exp(x), sin(x), cos(x), sinh(x), cosh(x), tanh(x), arctanh(x)等一些常见的函数功能。具体请看代码

 /*============================================================================*\
*
* 模拟实现 math.h 库中的函数
*
* 樊列龙 2013/7/1
*
\*============================================================================*/ #include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstdio> using namespace std; typedef int MODE; // 计算sin(x)时采用弧度还是角度
const int BY_RADIDAN = ; // 弧度
const int BY_ANGLE = ; // 角度 const double RATIO = 0.01745329251994; // 角度转弧度的转换率 long Factorial( long x ); // 阶乘
double Pow( double x, double y = ); // 求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( == x || == x )
{
return ;
} long ans = ;
for( int i = ; 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,/y);
} // 计算绝对值
double Fabs( double x )
{
if( x < -1e-)
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/( * PI() ) ) ) * * PI();
if( == x )
return ; double sum = , fs = x, fm = , t, t1 = ; //求和、分子、分母、精度、t1表示符号位
int n=; //项数 t = fs / fm; //精度赋值
while( Fabs(t) >= 1e-) //循环条件
{
sum = sum + t; //求和
n++; //基数增加
fs = fs * x * x; //新分子
fm = fm * ( *n - ) * ( *n - ); //新分母
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 = ; sum = 1.0;
term = 1.0; while(Fabs(term) > 1e-)
{
term = term * x * x / (n * (n-)) * (-1.0);
sum = sum + term;
n += ;
} 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 = ;
double sum = , term = x, numer = x, denom = ;
while(Fabs(term) > 1e-)
{
sum += term; // 求和
numer = numer * x * x; // 分子
denom = n+; // 分母
term = numer/denom; // 精度
n += ; // 计数
} return sum;
} // ln(x) = 2 arctanh((x-1)/(x+1))
// 调用了Arctanh(double) 方法
double Ln(double x)
{
return * Arctanh((x-)/(x+));
} // 求e^x 用于Pow( double, double )调用
// e^x = 1+x+(x^2)/2!+(x^3)/3!+...
// 精度为7位
double Exp( double x )
{
double ret = , term = x, numer = x, denom = ;;
int n = ;
while(Fabs(term) > 1e-)
{
ret += term; // 求和
numer *= x; // 分子
denom = denom * (n+); // 分母
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 = , b = ;
double m = 1.0, sum = 1.0; while( Fabs(m) > 1e- )
{
b = -b;
m = double(b) / a;
sum = sum + m;
a = a + ;
}
return * sum;
} //==============================================================================
void drow_line(int i = ,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 = ,
int min = ,
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(); cout << "\t\t\t\t*** 主菜单选项 ***" << endl; cout << "\t";
drow_line(); cout << left;
cout << "\t " << setw() << "1. 取整 Int( x )";
cout << setw() << "2. 计算 sinh( x )" << endl;
cout << "\t " << setw() << "3. 计算 sin( x )";
cout << setw() << "4. 计算 n^2 " << endl;
cout << "\t " << setw() << "5. 计算 n!";
cout << setw() << "6. 计算 cosh( x ) " << endl;
cout << "\t " << setw() << "7. 计算 cos( x )";
cout << setw() << "8. 计算 x^y" << endl;
cout << "\t " << setw() << "9. 计算 y√x ";
cout << setw() << "10. 计算 tanh( x ) " << endl;
cout << "\t " << setw() << "11. 计算 Π";
cout << setw() << "12. 计算 tan( x )" << endl;
cout << "\t " << setw() << "13. 计算 x^3";
cout << setw() << "14. 计算 3√x" << endl;
cout << "\t " << setw() << "0. 退出系统" << endl; cout << "\t";
drow_line(); cout << endl << endl;
drow_line(,"><");
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 :
cout << "是否退出?(Y/N)";
if(choos())
exit();
break;
case :
check_input(x);
ansInt = Int(x);
drow_line(,"**");
cout << "Int(" << x << ") = " << ansInt << endl;
pause();
break;
case :
check_input(x);
ans = Sinh(x);
drow_line(,"**");
cout << "sinh(" << x << ") = " << ans << endl;
pause();
break;
case :
check_input(x);
ans = Sin(x);
drow_line(,"**");
cout << "sin(" << x << ") = " << ans << endl;
pause();
break;
case :
check_input(x);
ans = Square(x);
drow_line(,"**");
cout << x << "^2 = " << ans << endl;
pause();
break;
case :
check_input(xi, " 请输入整数n: ");
ansInt = Factorial(xi);
drow_line(,"**");
cout << xi << "! = " << ansInt << endl;
pause();
break;
case :
check_input(x);
ans = Cosh(x);
drow_line(,"**");
cout << "cosh(" << x << ") = " << ans << endl;
pause();
break;
case :
check_input(x);
ans = Cos(x);
drow_line(,"**");
cout << "cos(" << x << ") = " << ans << endl;
pause();
break;
case :
check_input(x, " 请输入数据 x y : ");
check_input(y, "");
ans = Pow(x,y);
drow_line(,"**");
cout << x << "^" << y << " = " << ans << endl;
pause();
break;
case :
check_input(x, " 请输入数据 x y : ");
check_input(y, "");
ans = gen(x,y);
drow_line(,"**");
cout << y << "√" << x << " = " << ans << endl;
pause();
break;
case :
check_input(x);
ans = Tanh(x);
drow_line(,"**");
cout << "tanh(" << x << ") = " << ans << endl;
pause();
break;
case :
ans = PI();
drow_line(,"**");
cout << "π = " << ans << endl;
pause();
break;
case :
check_input(x);
ans = Tan(x);
drow_line(,"**");
cout << "tan(" << x << ") = " << ans << endl;
pause();
break;
case :
check_input(x);
ans = Cube(x);
drow_line(,"**");
cout << x << "^3 = " << ans << endl;
pause();
break;
case :
check_input(x);
ans = gen(x,);
drow_line(,"**");
cout << "3√" << x << " = " << ans << endl;
pause();
break;
default:
break;
}
}
return ;
}

执行结果:

自己模拟实现math.h中的函数的更多相关文章

  1. C语言中math.h中常用的函数

    1.绝对值 ①函数原型: int abs(int x); 函数功能: 求整数x的绝对值 int number=-1234; abs(number); ②函数原型:double fabs(double ...

  2. FUNCS.H中的函数声明

    /***************************************************************************                         ...

  3. math.h中的常量

    类似于Matlab中经常用到的一些常量,C++里边也是有的.(经查源文件无意中看到) 写入如下代码: #include<iostream> #include<iomanip> ...

  4. 转载:Windows下stdlib.h与glut.h中exit()函数重复定义的解决方案

    最近用到 OpenGL的第三方库Glut,碰到了exit()这个函数在stdlib.h与glut.h两个头文件中重复定义的情况,解决方案如下: 打开glut.h,找到exit()函数定义的地方(144 ...

  5. 头文件string.h中的函数及使用方法

    来源:http://blog.csdn.net/tsyj810883979/article/details/5116817 字符串拷贝1 @函数名称:   strdup函数原型:   char *st ...

  6. ios math.h 常用数学函数

    1. 三角函数  double sin (double);正弦  double cos (double);余弦  double tan (double);正切  2 .反三角函数  double as ...

  7. 有关linux中,<math.h>的调用方法

    h{font-weight:bold;color:green;font-size:105%} p{font-size:100%} linux下C语言程序中,若要用到math.h中的函数(如:sin() ...

  8. [Swift]数学库函数math.h | math.h -- mathematical library function

    常用数学函数 1. 三角函数 double sin (double);//正弦 double cos (double);//余弦 double tan (double);//正切 2 .反三角函数 d ...

  9. iOS math.h数学函数

    在实际工作中有些程序不可避免的需要使用数学函数进行计算,比如地图程序的地理坐标到地图坐标的变换.Objective-C做为ANSI C的扩展,使用C标准库头文件<math.h>中定义的数学 ...

随机推荐

  1. 一些CSS命名规则

    一些CSS命名规则 头:header 内容:content/containe 尾:footer 导航:nav 侧栏:sidebar 栏目:column 页面外围控制整体布局宽度:wrapper 左右中 ...

  2. GitHub 菜鸟使用

    之前有用过一次,但是一直弄不明白怎么用,今天我又试了一下,成功了,现在我就记录下来,为了以后的使用以及帮助那些跟我原先一样不会用的同学 进入正题: Step 1: 注册GitHub账号 https:/ ...

  3. 图文:TF卡和SD卡的区别及什么是TF卡?什么是SD卡

    小型存储设备凭借低廉的价格.多样化的品种.实用等特性大量充斥在大家身边,比如智能手机手机上.数码照相机上.游戏机上(一般是掌机)等都小型电子设备都频繁的使用到这种统称为SD的产品,比如TF卡和SD卡( ...

  4. (14)[Xamarin.Android] 异步的网络图片下载

    原文 [Xamarin.Android] 异步的网络图片下载 在设计要从网络上接大量数据并且显示在Android Listview中,而这些资料是利用Json格式传送并且数据中包含这图片档案. 那在X ...

  5. IP地址获取到为0:0:0:0:0:0:0:1

    引用 13 楼 oXiaoShe 的回复: Quote: 引用 11 楼 ahjsdzm 的回复: [Quote=引用 9 楼 huazaiyou 的回复:]最近在进行web开发时,遇到了reques ...

  6. Cppcheck软件使用

    一款开源源码检测工具.简单易用. 官网网址:http://cppcheck.sourceforge.net/ 软件可直接官网下载. [plain] view plaincopy Features Ou ...

  7. ldap理论属于概念缩略词

    Standalone LDAP Daemon, slapd(standalone lightweight access protocol) ldap 389 default listener port ...

  8. #include <array>

    array是静态数组,在栈上,不可以变长 vector比array更常用 不需要变长,容量较小,用array 需要变长,容量较大,用vector 1 array 1 array新数组 //std::a ...

  9. XMPP安装中遇到需要卸载openfire的步骤

    首先,确保你已经关掉了openfire打开终端 (在应用程序—>实用工具—>)输入以下命令sudo rm -rf /Library/PreferencePanes/Openfire.pre ...

  10. Struts2.x教程(一) Struts2介绍

    一.Struts2是什么 Struts2是在WebWork2基础发展而来的.和Struts1一样, Struts2也是基于MVC的web层框架. 那么既然有了Struts1,为何还要Struts2? ...