自己模拟实现math.h中的函数
之前一直都很迷惑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中的函数的更多相关文章
- C语言中math.h中常用的函数
		
1.绝对值 ①函数原型: int abs(int x); 函数功能: 求整数x的绝对值 int number=-1234; abs(number); ②函数原型:double fabs(double ...
 - FUNCS.H中的函数声明
		
/*************************************************************************** ...
 - math.h中的常量
		
类似于Matlab中经常用到的一些常量,C++里边也是有的.(经查源文件无意中看到) 写入如下代码: #include<iostream> #include<iomanip> ...
 - 转载:Windows下stdlib.h与glut.h中exit()函数重复定义的解决方案
		
最近用到 OpenGL的第三方库Glut,碰到了exit()这个函数在stdlib.h与glut.h两个头文件中重复定义的情况,解决方案如下: 打开glut.h,找到exit()函数定义的地方(144 ...
 - 头文件string.h中的函数及使用方法
		
来源:http://blog.csdn.net/tsyj810883979/article/details/5116817 字符串拷贝1 @函数名称: strdup函数原型: char *st ...
 - ios math.h 常用数学函数
		
1. 三角函数 double sin (double);正弦 double cos (double);余弦 double tan (double);正切 2 .反三角函数 double as ...
 - 有关linux中,<math.h>的调用方法
		
h{font-weight:bold;color:green;font-size:105%} p{font-size:100%} linux下C语言程序中,若要用到math.h中的函数(如:sin() ...
 - [Swift]数学库函数math.h |  math.h -- mathematical library function
		
常用数学函数 1. 三角函数 double sin (double);//正弦 double cos (double);//余弦 double tan (double);//正切 2 .反三角函数 d ...
 - iOS math.h数学函数
		
在实际工作中有些程序不可避免的需要使用数学函数进行计算,比如地图程序的地理坐标到地图坐标的变换.Objective-C做为ANSI C的扩展,使用C标准库头文件<math.h>中定义的数学 ...
 
随机推荐
- Labview常用快捷键
			
对象调整和移动快捷键 Shift-click 选择多个对象,在现有选择的基础上添加对象 方向键 ...
 - php数据类型有哪些?
			
php数据类型有哪些?有三大类1.基本数据类型 1.1整型 $a = 0123; // 八进制数(是以0开头) 83 $a = 0x1A; // 十六进制数 26 1.2小数 ...
 - C++设计模式之建造模式
			
#include <iostream>using namespace std; class ApplePhone { public: virtual void buildCamera()= ...
 - 请求(Request)的参数(Parameter)里包含特殊字符(#等)的正确处理方式
			
遇到一个问题 在一个地址链接(URL)里使用 url?param1=val1¶m2=val2 的方式传递参数,结果在获取参数值时发现不是当初设定的值. 具体案例 以特殊字符井号(#)为 ...
 - 限制转交订单-采购直接批准PO
			
应用 Oracle Purchasing 层 Level Function 函数名 Funcgtion Name CUXPOXPOEPO 表单名 Form Name POXPOEPO 说明 Des ...
 - Puppet的执行过程
			
图1 Puppet工作流程 1. 客户端Puppetd向Master发起认证请求,或使用带签名的证书. 2. Master告诉Client你是合法的. 3. 客户端Puppetd调用Facter,Fa ...
 - javascript打乱数组顺序-----1
			
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
 - 关于jquery的each的操作;
			
<!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...
 - Walking Ant(bfs)
			
Walking Ant Time Limit: 2 Seconds Memory Limit: 65536 KB Ants are quite diligent. They sometime ...
 - 三维CAD塑造——基于所述基本数据结构一半欧拉操作模型
			
三维CAD塑造--基于所述基本数据结构一半欧拉操作模型(elar, B_REP) (欧拉操作 三维CAD建模课程 三维CAD塑造 高曙明老师 渲染框架 brep 带洞 带柄 B_REP brep ...