...
... a domain error occurs if an input argument is outside the domain over which the mathematical function is defined.
Paragraph 3 states:
... a pole error (also known as a singularity or infinitary) occurs if the mathematical function has an exact infinite result as the finite input argument(s) are approached in the limit.
...
Function | Domain | Range | Pole |
---|---|---|---|
|
| No | No |
asin(x) | -1 <= x && x <= 1 | YesYes | No |
atan(x) | None | Yes | No |
|
| No | No |
|
| Yes | No |
asin(x) | None | Yes | No |
|
| Yes | Yes |
| None | Yes | No |
| None | Yes | No |
| None | Yes | No |
|
| No | Yes |
|
| No | Yes |
|
| Yes | No |
logb(x) | x != 0 | Yes | Yes |
| None | Yes | No |
| None | Yes | No |
|
| Yes | Yes |
|
| No | No |
erf(x) | None | Yes | No |
| None | Yes | No |
|
| Yes | Yes |
| None | Yes | No |
|
| Yes | No |
| None | Yes | No |
| None | Yes | No |
| None | Yes | No |
...
See FLP03-C. Detect and handle floating-point errors for more details on how to detect floating-point errors.anchor
Denormal Arguments
Certain functions may produce range errors specifically when applied with a denormal argument. These functions are:
...
asin(
...
)
...
, asinh(
...
)
...
, atan(
...
)
...
, atanh(
...
)
...
, and erf(
...
These functions when evaluated )
. When evaluated with a denormal argument can , these functions can produce an inexact, denormal value, which is an underflow error. Subclause 7.12.1, paragraph 6, of the C Standard [ISO/IEC 9899:2011] defines the following behavior for floating-point underflow:
...
Specifically, for implementations that support Annex F but do not support denormalized numbers, the following functions and arguments will cause range errors.
Function | Arguments |
---|---|
fmod() | ((min+denorm),min) |
remainder() | ((min+denorm),min) |
remquo() | ((min+denorm),min,quo) |
If denormal results are supported, the returned value is exact and there will not be a range error. When dealing with fmod()
, Subclause subclause F.10.7.1, paragraph 2, of the C Standard [ISO/IEC 9899:2011] states:
...
Subclause F.10.7.2, paragraph 2, and Subclause subclause F.10.7.3, paragraph 2 of the C Standard [ISO/IEC 9899:2011] covers cover remainder()
and and remquo()
for when denormal results are supported.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <math.h> void func(double x) { double result; if (isless(x, 0.0)) { /* Handle domain error */ } result = sqrt(x); } |
...
Noncompliant Code Example (sinh()
, Range Errors)
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <errno.h> #include <math.h> #if defined(math_errhandling) \ && (math_errhandling & MATH_ERREXCEPT) #include <fenv.h> #pragma STD FENV_ACCESS ON #endif void func(double x) { double result; errno = 0; result = sinh(x); #if defined(math_errhandling) \ && (math_errhandling & MATH_ERREXCEPT) feclearexcept(FE_ALL_EXCEPT); #endif #if !defined(math_errhandling) \ || (math_errhandling & MATH_ERRNO) if (errno != 0) { /* Handle range error */ } #endif #if defined(math_errhandling) \ && (math_errhandling & MATH_ERREXCEPT) if (fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) != 0) { /* Handle range error */ } #endif } |
...
...
Noncompliant Code Example (pow()
)
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <errno.h> #include <math.h> #if defined(math_errhandling) \ && (math_errhandling & MATH_ERREXCEPT) #include <fenv.h> #pragma STDC FENV_ACCESS ON #endif void func(double x, double y) { #if defined(math_errhandling) \ && (math_errhandling & MATH_ERREXCEPT) feclearexcept(FE_ALL_EXCEPT); #endif errno = 0; double result; if (((x == 0.0f) && islessequal(y, 0.0)) || isless(x, 0.0)) { /* Handle domain or pole error */ } result = pow(x, y); #if !defined(math_errhandling) \ || (math_errhandling & MATH_ERRNO) if (errno != 0) { /* Handle range error */ } #endif #if defined(math_errhandling) \ && (math_errhandling & MATH_ERREXCEPT) if (fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) != 0) { /* Handle range error */ } #endif } |
Noncompliant Code Example (asin()
,
...
Denormal Argument)
This noncompliant code example determines the arcsin of x:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <math.h> void func(float x) { float result; result = asin(x); /* ... */ } |
Compliant Soluction (asin()
,
...
Denormal Argument)
Because this function has no domain errors but may have range errors, the programmer must detect a range error and act accordingly:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <errno.h> #include <math.h> #if defined(math_errhandling) \ && (math_errhandling & MATH_ERREXCEPT) #include <fenv.h> #pragma STDC FENV_ACCESS ON #endif void func(float x) { float result; errno = 0; result = asin(x); #if defined(math_errhandling) \ && (math_errhandling & MATH_ERREXCEPT) feclearexcept(FE_ALL_EXCEPT); #endif #if !defined(math_errhandling) \ || (math_errhandling & MATH_ERRNO) if (errno != 0) { /* Handle range error */ } #endif #if defined(math_errhandling) \ && (math_errhandling & MATH_ERREXCEPT) if (fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) != 0) { /* Handle range error */ } #endif } |
...
Risk Assessment
Failure to prevent or detect domain and range errors in math functions may cause unexpected results.
...
Bibliography
[ISO/IEC 9899:2011] | Subclause 7.3.2, "Conventions" |
[Plum 1985] | Rule 2-2 |
[Plum 1989] | Topic 2.10, "conv—Conversions and Overflow" |
[UNIX 1992] | System V Interface Definition (SVID3) |
...