错误情况的处理
除非另有明确说明,否则对于所有输入实参的可表示值,<math.h>头文件中函数的行为都是明确规定的。每个函数都像单个操作一样执行,而不会引发SIGFPE,并且不会产生任何域异常、极点异常或者溢出范围异常(除了反映函数的结果)。
对于所有函数,如果参数超出函数定义的范围将会发生域错误(domain error)。每个函数的描述都列出了所有必需的域错误;实现可以定义额外的域错误,只要这些错误与函数的数学定义一致;例如:如果函数的数学域不包括无穷大,而实现支持无穷大,则允许作为参数的无穷大引发域错误。发生域错误时,函数会返回一个实现定义值。如果表达式math_errhandling & MATH_ERRNO为非0值,则errno值为EDOM;如果表达式math_errhandling & MATH_ERREXCEPT为非0值,将引发域异常("invalid" floating-point exception)。
因为有限输入参数接近极限,数学函数具有无限结果时,会出现极点错误(pole error);例如:log(0.0)。每个函数的描述都列出了所有必需的极点错误;实现可以定义额外的极点错误,只要这些错误与函数的数学定义一致。发生极点错误时,函数会返回一个实现定义值。如果表达式math_errhandling & MATH_ERRNO为非0值,则errno值为ERANGE;如果表达式math_errhandling & MATH_ERREXCEPT为非0值,将引发极点异常("divide-by-zero" floaing-point exception)。
当函数的数学结果由于极端大小而无法使用指定类型的对象表示时,将发生范围错误(range error)。每个函数的描述都列出了所有必需的范围错误;实现可以定义额外的范围错误,只要这些错误与函数的数学定义一致,并且是溢出(overflow)或者下溢(underflow)的结果。
如果数学结果的大小是有限的,但在没有异常舍入误差的情况下指定类型的对象无法表示数学结果,将会发生溢出(overflow)。如果浮点结果溢出并且默认的舍入方式生效,函数将根据返回值的类型返回HUGE_VAL、HUGE_VALF或者HUGE_VALL,根据正确结果返回与正确结果相同的符号。如果表达式math_errhandling & MATH_ERRNO为非0值,则errno值为ERANGE;如果表达式math_errhandling & MATH_ERREXCEPT为非0值,将引发溢出异常("overflow" floating-point exception)。
如果数学结果的数量级太小,以至于在没有异常舍入误差的情况下指定类型的对象无法表示数学结果,将会发生下溢(underflow)。如果发生下溢,函数将返回一个实现定义值,其绝对值不大于对应浮点类型的最小正规格化数(normalized number)。如果表达式math_errhandling & MATH_ERRNO为非0值,errno值是否为ERANGE将由实现定义;如果表达式math_errhandling & MATH_ERREXCEPT为非0值,是否会引发下溢异常("underflow" floating-point exception)将由实现定义。
如果发生域错误、极点错误或者范围错误,并且表达式math_errhandling & MATH_ERRNO为0(这种情况下,数学错误使用浮点异常标记(floating-point exception flags),而不是使用errno。),errno可能被设置成对应的错误值,也可能保持不变。如果没有发生域错误、极点错误或者范围错误,errno应保持不变,其与math_errhandling的设置无关。