自己模拟实现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>中定义的数学 ...
随机推荐
- 众数问题(为什么只能输入一组数据,不能输入m组数据)
描述 所谓众数,就是对于给定的含有N个元素的多重集合,每个元素在S中出现次数最多的成为该元素的重数, 多重集合S重的重数最大的元素成为众数.例如:S={1,2,2,2,3,5},则多重集S的众数是2, ...
- Linux学习之nfs安装配置
安装疑难问题: 1.检查系统是否开启nfs服务:service nfs status 结果显示nfs: unrecognized service,说明系统没有安装nfs服务,so 安装之: 注意,yu ...
- Centos6.7 安装ReviewBoard2.5.7 问题记录
pip install ReviewBoard 1.修改pip源,默认源网络不畅 pip install -i http://pypi.douban.com/simple simplejson 2.p ...
- 区分IE9/IE8/IE7/IE6及其他浏览器-CSS hack
记录一下这些浏览器的hack如下: 一.IE9以及以下版本浏览器 对于IE8及其以下版本的浏览器,就是使用本文标题所提到的”\9″ hack.如下代码: .ie8_9{ color:blue; /*所 ...
- 我定制的jquery ui主题
打开网址 http://jqueryui.com/themeroller/,找到Gallery找到Redmond点击edit 将圆角设置成3px,让圆角更低调:将下面的每个Background的背景图 ...
- ueditor插件 -- 插入填空题
插入填空题,一个看似小小的需求,但是却是折腾了很9.主要产品那边的要求,空格上面要标有序号,并且再页面当中能够同步空格答案列表. 1.ueditor插件 插件入门,官方的例子还是很简单直接的,对于我们 ...
- linux mail 简操作
1. 如何查看linux的mailqueue 检查所传送的电子邮件是否送出,或滞留在邮件服务器中 语法:/usr/lib/sendmail -bp 2. 如何发送mail 1)将文件当做电子邮件的内容 ...
- Linux主要发行版本介绍
Linux主要发行版本介绍 1.Red Hat Linux Red Hat是一个比较成熟的Linux版本,无论在销售还是装机量上都比较可观.该版本从4.0开始同时支持Intel.Alpha及Sparc ...
- 再来一个学历重要性讨论——QQ技术群聊
----------------------------------------------------------------------- 正方:学历重要 大专,刚毕业那会太坑爹了.太受学历限制. ...
- hadoop源码eclipse环境搭建-源码获取阶段
就目前了解,结合eclipse阅读和编译hadoop源码用两种方式:svn和git. 根据官方指南http://wiki.apache.org/hadoop/EclipseEnvironment 推荐 ...