...
An example of a domain error is the square root of a negative number, such as sqrt(-1.0), which has no meaning in real arithmetic. On the other hand, 10 raised to the 1-millionth power, pow(10., 1e6), likely cannot be represented in an implementation's floating-point representation and consequently constitutes a range error. In both cases, the function will return some value, but the value returned is not the correct result of the computation.
...
| Code Block |
|---|
if (/* Arguments that will cause a domain error. */) { /* Handle domain error. */ } else { /* Perform computation. */ } |
Range Checking
Range errors cannot usually be prevented, so the most reliable way to handle range errors is to detect when they have occurred and act accordingly.
...
| Code Block |
|---|
#include <math.h>
#if defined(math_errhandling) \
&& (math_errhandling & MATH_ERREXCEPT)
#include <fenv.h>
#endif
/* ... */
#if defined(math_errhandling) \
&& (math_errhandling & MATH_ERREXCEPT)
feclearexcept(FE_ALL_EXCEPT);
#endif
errno = 0;
/* Call the function. */
#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
|
See FLP03-C. Detect and handle floating-point errors for more details on how to detect floating-point errors.
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <math.h>
void func(double x) {
double result;
if (isless(x, 0)) {
/* Handle domain error. */
}
result = sqrt(x);
} |
| Anchor | ||||
|---|---|---|---|---|
|
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <errno.h>
#include <math.h>
#if defined(math_errhandling) \
&& (math_errhandling & MATH_ERREXCEPT)
#include <fenv.h>
#endif
void func(double x) {
double result;
result = sinh(x);
#if defined(math_errhandling) \
&& (math_errhandling & MATH_ERREXCEPT)
feclearexcept(FE_ALL_EXCEPT);
#endif
errno = 0;
#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
} |
| Anchor | ||||
|---|---|---|---|---|
|
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <errno.h>
#include <math.h>
#if defined(math_errhandling) \
&& (math_errhandling & MATH_ERREXCEPT)
#include <fenv.h>
#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.f) && islessequal(y, 0)) || (isless(x, 0))) {
/* Handle domain 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
} |
Risk Assessment
...
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
FLP32-C | mediumMedium | probableProbable | mediumMedium | P8 | L2 |
Automated Detection
Tool | Version | Checker | Description |
|---|---|---|---|
5.0 |
| Can detect violations of this rule with CERT C Rule Pack |
...