在C语言中,math.h中定义的各种数学函数的实现在libm里,而每个 libm 实现都不同。gcc的glibm 中数学函数的实现完全是平台依存的,在 x86 机器上,能调用 FPU 指令的就用 FPU(比如 sqrt() 就实际上调用 FSQRT,log() 调用的是 FYL2X),否则再自己实现。
一、C语言中,math.h中定义的各种数学函数的实现
在C语言中,math.h中定义的各种数学函数的实现在libm里,而每个 libm 实现都不同。gcc的glibm 中数学函数的实现完全是平台依存的,在 x86 机器上,能调用 FPU 指令的就用 FPU(比如 sqrt() 就实际上调用 FSQRT,log() 调用的是 FYL2X),否则再自己实现。
首先需要明确的是,CPU只支持加、减、乘、除以及一些布尔逻辑运算,严格的说,CPU仅支持布尔运算,其它的一切运算都是基于布尔运算设计出来的复杂电路。当然我这句话还是相当不全面的,比如CPU还支持一些为其它工作而专门优化的运算如3D变幻之类,但这些我们暂时不考虑。问题来了,既然CPU只支持+-*/,那如何计算出幂运算呢?比如3的5次方,CPU如何计算?很简单,我们只要把这个运算转换成只含有加减乘除的运算就可以了,3的5次方明显等于3*3*3*3*3,这样CPU就可以计算了。
如果需要软件实现,方法基本上是泰勒级数。当然对于 sin 这类,可以用专门的优化算法,比如 CORDIC。
CPU 中的电路基本上也就是泰勒级数。
延伸阅读:
二、常用函数举例
求绝对值
1、abs(a)
#include <stdlib.h>
int abs( int n );
这个函数可以求绝对值,但是它包含在<stdlib.h>头文件中,不要搞混了~
2、fabs(a)
#include <math.h>
double fabs (double arg);
这个函数在math头文件中,传入参数可以是整型或double型,输出是double的。
那如果传入参数不是这两种呢?我们可以使用它的孪生函数:
long double fabsl(long double arg);
float fabsf(float arg);
在原函数名后面加’l’或者’f’,可以获得两个新函数,功能同fabs(),但是传入参数的类型不同。
求两者中最大/小值
1、fmax(a, b)
两数中求最大值。
double fmax( double x, double y );
传入参数可以是整型或double型,它同样有变体函数,fmaxl、fmaxf,用法如下:
float fmaxf( float x, float y );
long double fmaxl( long double x, long double y );
2、fmin(a, b)
两数中求最小值,用法和fmax一样。
double fmin( double x, double y );
float fminf( float x, float y );
long double fminl( long double x, long double y );