大部分C90数学库中都声明了double类型参数和double类型返回值的函数,例如:
double sin(double);
double sqrt(double);
C99和C11库为所有这些函数都提供了float类型和long double类型的函数。这些函数的名称由原来函数名加上f或l后缀构成,例如:
float sinf(float); /* sin()的float版本 */
long double sinl(long double); /* sin()的long double版本 */
有了这些不同精度的函数系列,用户可以根据具体情况选择最效率的类型和函数组合。
C99还新增了一些科学、工程和数学运算中常用的函数。在许多情况下,这些函数的的返回值都可以使用现有的函数计算得出,但是新函数计算得更快更精确。例如,log1p(x)表示的值与log(1+x)相同,但是log1p(x)使用了不同的算法,对于较小的x值而言计算更精确。因此,可以使用log()函数作普通运算,但是对于精确要求较高且x值较小时,用log1p()函数更好。
除这些函数以外,数学库中还定义了一些常量和与数学分类、舍入相关的函数。例如,可以把值分别为无穷值、非数(NaN)、正常值、低于正常值、真零。[NaN是一个特别的值,用来表示一个不是数的值。例如,asin(2.0)返回NaN,因为定义了asin()函数的参数必需是-1~1范围内的值。低于正常的值是比使用全精度表示的最小值还要小的数。]还有一些专用的比较函数,如果一个或多个参数是非正常值时,函数的行为与标准的关系运算符不同。
使用C99的分类方案可以检测计算的规律性。例如,math.h中的isnormal()宏,如果其参数是一个正常的数,则返回真。下面的代码使用该宏在num不正常时结束循环:
#include简而言之,数学库为更好地控制如何计算浮点数,提供了扩展支持。//为了使用isnormal() ... float num = 1.7e-19; float numprev = num; while(isnormal(num)) //当num为全精度的float类型值 { numprev = num; num /= 13.7f; }