Wiki Markup |
---|
C99 Section 7.12.1 defines two types of errors that relate specifically to math functions (as defined in {{math.h}}) \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] |
a domain error occurs if an input argument is outside the domain over which the mathematical function is defined.
a range error occurs if the mathematical result of the function cannot be represented in an object of the specified type, due to extreme magnitude.
An example of a domain error is
It is important to prevent or detect domain errors and range errors in the C99 math functions (as defined in math.h
) before using the results in further computations.
Most of the math functions can fail if they are given arguments that do not produce a proper result. For example, the square root of a negative number, such as sqrt(-1.0)
, which has no meaning in real arithmetic. This is known as a domain error; the argument is outside the domain over which the function is defined. For another exampleSimilarly, ten raised to the one-millionth power, pow(10., 1e6)
, likely cannot be represented in an implementation's floating point representation . This is known as and therefore constitutes a range error; the result cannot be represented as a proper double
number. In all such error .
In both cases, the function will return some value, but the value returned is not the correct result of the computation.
...
However, for some functions it is not practical to use bounds-checking to prevent all errors. In the above pow
example, the bounds check does not prevent the pow(10., 1e6)
range error. In these cases detection must be used, either in addition to bounds checking or instead of bounds checking.
...
Wiki Markup |
---|
However, this code may produce a _domain error_ if {{x}} is not in the range \[-1, \+1\]. |
...
The following compliant solution uses bounds checking to ensure that there is not a domain error.
Code Block | ||
---|---|---|
| ||
double x, result; /* Set the value for x */ if ( islessequal(x,-1) || isgreaterequal(x, 1) ){ /* handle domain error */ } result = acos(x); |
...
However, this code may produce a domain error if both x
and y
are zero.
Compliant Solution
The following compliant solution tests the arguments to ensure that there is not a domain error.
Code Block | ||
---|---|---|
| ||
double x, y, result; /* Set the value for x and y */ if ( (x == 0.f) && (y == 0.f) ) { /* handle domain error */ } result = atan2(y, x); |
...
However, this code may produce a domain error if x
is negative and a range error if x
is zero.
Compliant Solution
The following compliant solution tests the suspect arguments to ensure that no domain errors or range errors are raised.
Code Block | ||
---|---|---|
| ||
double result, x; /* Set the value for x */ if (islessequal(x, 0)) { /* handle domain and range errors */ } result = log(x); |
...
However, this code may produce a domain error if x
is negative and y
is not an integer, or if x
is zero and y
is zero. A domain error or range error may occur if x
is zero and y
is negative, and a range error may occur if the result cannot be represented as a double
.
...
This code only performs bounds-checking on x
and y
. It prevents domain errors and some range errors, but does not prevent range errors where the result cannot be represented as a double
(see the Error Checking section below regarding ways to mitigate the effects of a range error).
Code Block | ||
---|---|---|
| ||
double x, y, result; if (((x == 0.f) && islessequal(y, 0)) || (isless(x, 0) && !isInteger(y))) { /* handle domain and range errors */ } result = pow(x, y); |
...
However, this code may produce a domain error if x
is negative.
Compliant Solution
The following compliant solution tests the suspect argument to ensure that no domain error is raised.
Code Block | ||
---|---|---|
| ||
double x, result; if (isless(x, 0)){ /* handle domain error */ } result = sqrt(x); |
...
Wiki Markup |
---|
The {{sqrt()}} function returns zero when given a negative argument. The {{pow()}} function returns a very large number (appropriately positive or negative) on an overflow _range error_. This very large number is defined in {{<math.h>}} as described by C99 \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\]: |
...