C标准库源码解剖(15):数学函数库math.h, tgmath.h和complex.h

    数学库是一个庞大的库,而且数学函数的实现一般要涉及到特有的数值算法,因此这里也是作一个概述性的介绍。标准C中的数学库有3个头文件math.h, tgmath.h和complex.h,其中tgmath.h和complex.h是C99中引入的。标准C中定义的数学函数主要是初等函数,包括绝对值函数、高斯函数(即求最近整数)、指数函数、对数函数、幂函数、三角函数与反三角函数、双曲函数与反双曲函数等。非初等函数主要有误差函数、gamma函数及其自然对数。其他的还有浮点数分类函数、浮点数比较函数。glibc的数学库实现在math目录下。
    数学函数在math.h中声明,复数运算及其函数在complex.h中声明。C99对每个数学函数增加了两个分别针对float和long double的版本,只要在函数名后加f和l即可。由于每个函数对不同的参数类型有多个版本,使用起来不方便,因此C99在tgmath.h中定义了通用类型宏,这些宏与原始的针对double类型的数学函数同名,它会根据传过来的实参类型自动调用多个版本中的某一个版本。若函数结果无法表示为返回类型的值,则errno设置为ERANGE,并返回该类型的同符号的最大可浮点数值,在C89中为宏HUGE_VAL的值,C99中还提供了宏HUGE_VALF,HUGE_VALL。
   
    math.h中所有的标准函数接口如下:
    1、abs,labs,llabs,div,ldiv,lldiv:整型的绝对值,及除法运算,这些数学函数在stdlib.h中定义。
    2、fabs:返回double型参数的绝对值,C99中增加了对应的f版本和l版本。
    3、ceil,floor,lrint,llrint,lround,llround,mearbyint,round,rint,trunc:计算与浮点数参数接近的整数,有对应的f和l版本,除ceil和floor外都是C99中新增的。返回整数值,但返回类型很多都设为浮点型,因为得到的整数可能太大,无法用整型表示。
    4、fmod,remainder,remquo:返回x/y的浮点数余数的近似值,有对应的f和l版本,除fmod外都是C99中新增的。
    5、frexp,ldexp,modf,scalbn,scalbln:获取浮点数的整数和小数部分,scalbn/scalbln将浮点数x乘以b**n,其中b是FLT_RADIX。都有对应的f和l版本,除frexp外都是C99中新增的。
    6、exp,exp2,expml,logb/ilogb,log,log10,log2,log1p:计算e**x,、2**x、 e**(x-1)、logb/ilogb从浮点数x的表示中取指数、 自然对数、10为底的对数、2为底的对数,都有对应的f和l版本,除exp,log,log10外都是C99中增加的。
    7、cbrt,fma,hypot,pow,sqrt:计算x的立方根、x*y+z、x**2+y**2、x**y、x的非负平方根,有对应的f和l版本,除pow,sqrt外都是C99中增加的。
    8、rand,srand,RAND_MAX:生成伪随机数的函数,在stdlib.h中定义。
    9、cos,sin,tan,cosh,sinh,tanh:余弦、正弦、正切、双曲余弦、双曲正弦、双曲正切函数,参数x为弧度。有对应的f和l版本(C99中增加)。
    10、acos,asin,atan,atan2,acosh,asinh,atanh:反三角函数,有对应的f和l版本,除acos,asin,atan,atan2外都是C99中增加的。
    11、fdim,fmax,fmin:计算x与y的正差值、两个参数中较大的值、两个参数中较小的值。
    12、erf,erfc,lgamma,tgamma:计算误差函数、1-erf(x)、x的gamma函数的自然对数、x的gamma函数。有对应的f和l版本,都是C99中引入的。
    13、fpclassify,isfinite,isinf,isnan,isnormal,signbit:给浮点数分类返回FP_INFINITE,FP_NAN,FP_NOR MAL,FP_SUBNORMAL或FP_ZERO值之一、是否是有限数(既不是无限大也不是NaN)、是否是无限大、是否是NaN、是否是规格化数、是否是负数。都是C99中引入的。
    14、copysign,nan,nextafter,nexttoward:返回采用y的符号后的x、返回静态NaN、返回y方向上x的下一个浮点数值、与nextaftter等价只是y为long double型。有对应的f和l版本,都是C99中引入的。
    15、isgreater,isgreaterequal,isless,islessequal,islessgreater,isunordered:比较两个浮点数。若两个浮点数中有一个或两个为NaN,则它们是无序的,都是C99中引入的。
   
    对复数及其运算的支持由C99提供,在complex.h中,接口如下:
    1、complex,_Complex_I,imaginary,_Imaginary_I,I:复数类型、虚数类型、虚数单位i。
    2、CX_LIMITED_RANGE:这个标准杂注打开时表示可以使用复数乘法、除法与绝对值运算的"x+yi"实现版本(这个实现是不完善的,用acosx+ibsinx来实现才比较完善)。
    3、ccos,csin,ctan,cacos,casin,catan:复数域内的三角函数,有对应的f和l版本。
    4、ccosh,csinh,ctanh,cacosh,casinh,catanh:复数域内的双曲函数,有对应的f和l版本。
    5、cexp,clog,cabs,cpow,csqrt:复数域内的指数、对数、绝对值、幂函数,有对应的f和l版本。
    6、carg,cimag,creal,conj,cproj:获取象限角、虚数部分、实数部分、a=x及b=-y、Riemann球上的投影,有对应的f和l版本。
   
    通用类型宏:C99中引入,在tgmath.h中定义。它包含了头文件math.h和complex.h。通用类型T可以是float,double,long double,float complex,double complex或long double complex。REAL(T)表示与复数类型长度相同的实数类型。这些宏会根据传来的参数展开成特定的math.h或complex.h中的函数。

展开阅读全文

没有更多推荐了,返回首页