Prevent It is important to prevent or detect domain errors and range errors in the C99 math functions (as defined in math.h
) math functions 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)
, 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 example, ten raised to the one-millionth power, pow(10., 1e6)
, likely cannot be represented in any (current) an implementation's floating point representation. This is known as a range error; the result cannot be represented as a proper double
number. In all such error 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. For In the above pow
example, the above bounds check for pow()
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.
...
Non-Compliant Code Example
The following non-compliant code computes the arc cosine of the variable x
Code Block | ||
---|---|---|
| ||
double x, result;
/* Set the value for x */
result = acos(x);
|
Wiki Markup |
---|
ThisHowever, this code may produce a domain error if the argument {{x}} is not in the range \[-1, \+1\]. |
Code Block | ||
---|---|---|
| ||
double x, result;
result = acos(x);
|
Compliant Solution
This code 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);
|
...
Non-Compliant Code Example
This code may produce a domain error if both The following non-compliant code computes the arc tangent of the two variables x
and y
are zero.
Code Block | ||
---|---|---|
| ||
double x, y, result;
/* Set the value for x and y */
result = atan2(y, x);
|
However, this code may produce a domain error if both x
and y
are zero.
Compliant Solution
This code 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);
|
...
Non-Compliant Code Example
This code may produce a domain error if x is negative and a range error if x is zeroThe following non-compliant code determines the natural logarithm of x
.
Code Block | ||
---|---|---|
| ||
double result, x;
/* Set the value for x */
result = log(x);
|
However, this code may produce a domain error if x
is negative and a range error if x
is zero.
Compliant Solution
This code tests the suspect arguments to ensure that no domain 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);
|
...
Non-Compliant Code Example
The following non-compliant code raises x
to the {{y}}th power.
Code Block | ||
---|---|---|
| ||
double x, y, result;
result = pow(x, y);
|
However, this 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
.
...
...
double x, y, result;
result = pow(x, y);
Non-Compliant Code Example
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
.
...
Non-Compliant Code Example
This code may produce a domain error if x is negative.The following non-compliant code determines the square root of x
Code Block | ||
---|---|---|
| ||
double x, result; result = sqrt(x); |
However, this code may produce a domain error if x
is negative.
Compliant Solution
This code tests the suspect argument to ensure that no domain error is raised.
...