目录

在C语言中,math.h中定义的各种数学函数怎么实现

在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 );

一站式研发项目管理平台 PingCode

一站式研发项目管理平台 PingCode

支持敏捷\瀑布、知识库、迭代计划&跟踪、需求、缺陷、测试管理,同时满足非研发团队的流程规划、项目管理和在线办公需要。