...
... 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) |
...