Prevent or detect domain errors and range errors in 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)
, cannot be represented in any (current) 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.
Math Many math errors can be prevented by carefully bounds-checking the arguments before calling functions, and taking alternative action if the bounds are violated. In particular, the following functions should be bounds checked as follows:
Function | Bounds-checking |
---|---|
-1 <= x && x <= 1 | |
x != 0 || y != 0 | |
x >= 0 | |
x > 0 || (x == 0 && y > 0) || (x < 0 && y is an integer) | |
x >= 0 |
The calling function should take alternative action if these bounds are violatedHowever, for some functions it is not practical to use bounds-checking to prevent all errors. For 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.
Anchor | ||||
---|---|---|---|---|
|
acos( x ), asin( x )
...
This code may produce a domain error if x is negative and y is not an integer, or if x is zero and y less than or equal to is zero. A domain error or range error may also occur if x is zero and y is negative, and a range error may occur if the result cannot be represented as a double
.
Code Block | ||
---|---|---|
| ||
double x, y, result; result = pow(x, y); |
Non-Compliant
...
Code Example
This code tests only performs bounds-checking on x and y to ensure that there will be no range or domain errors. It prevents domain errors and some range errors, but does not prevent range errors where the result cannot be represented as a double
.
Code Block | ||
---|---|---|
| ||
double x, y, result; if (((x == 0.f) && islessequal(y, 0)) || (isless(x, 0) && !isInteger(y))) { /* handle domain and errorrange conditionerrors */ } result = pow(x, y); |
Anchor | ||||
---|---|---|---|---|
|
sqrt( x )
Non-Compliant Code Example
This code may produce a domain error if x is negative.
Code Block | ||
---|---|---|
| ||
double x, result; result = sqrt(x); |
Compliant Solution
This code tests the suspect argument to ensure that no domain error is raised.
...