...
See FLP03-C. Detect and handle floating-point errors for more details on how to detect floating-point errors.
...
Subnormal Numbers
A denormalized subnormal number is a nonzero number that does not use all of its precision bits [IEEE 754 2006 ]. They can be used to represent values that are closer to 0 than the smallest normal number (one that uses all of its precision bits). However, certain functions may produce range errors specifically when applied with a denormalized subnormal number. These functions are: asin()
, asinh()
, atan()
, atanh()
, and erf()
. When evaluated with a denormalized subnormal number, these functions can produce an inexact, denormalized valuesubnormal 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:
The result underflows if the magnitude of the mathematical result is so small that the mathematical result cannot be represented, without extraordinary roundoff error, in an object of the specified type. If the result underflows, the function returns an implementation-defined value whose magnitude is no greater than the smallest normalized positive number in the specified type; if the integer expression
math_errhandling & MATH_ERRNO
is nonzero, whethererrno
acquires acquires the valueERANGE
is is implementation-defined; if the integer expressionmath_errhandling & MATH_ERREXCEPT
is nonzero, whether the ‘‘underflow’’ floating-point exception is raised is implementation-defined.
Specifically, for implementations that support Annex F but do not support denormalized subnormal numbers, the following functions and arguments will cause range errors.
...
Implementations that support floating point arithmetic but does not support subnormals, such as IBM S/360 hex floating point or sloppy IEEE-754 implementations that skip subnormals (or "support" them by flushing them to zero) can return a range error when calling one of the following family of functions with the following arguments:
...
fmod
((min+
...
subnorm),min)
remainder
(
...
(min+
...
),min)subnorm
remquo
(
...
(
...
min+
...
),min,quo)subnorm
...
Where min
is the minimum value for the corresponding floating point type and subnorm
is a subnormal value.
These error cases are not an issue if Annex F is fully support. In this case, if subnormal results If denormalized results are supported, the returned value is exact and there will not cannot be a range error. When dealing with fmod()
, subclause F.10.7.1, paragraph 2, of the The C Standard [ISO/IEC 9899:2011] statesspecifies the following for the fmod()
, remainder()
and remquo()
functions:
When subnormal results are supported, the returned value is exact and is independent of the current rounding direction mode.
Subclause F.10.7.2, paragraph 2, and subclause F.10.7.3, paragraph 2 of the C Standard [ISO/IEC 9899:2011] cover remainder()
and remquo()
cover for when denormalized results subnormal results are supported.
Noncompliant Code Example (sqrt()
)
...
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()
,
...
Subnormal Number)
This noncompliant code example determines the arcsin of x:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <math.h> void func(float x) { float result = asin(x); /* ... */ } |
Compliant Soluction (asin()
,
...
Subnormal Number)
Because this function has no domain errors but may have range errors, the programmer must detect a range error and act accordingly:
...
[ISO/IEC 9899:2011] | Subclause 7.3.2, "Conventions" |
[IEEE 754 2006 ] | |
[Plum 1985] | Rule 2-2 |
[Plum 1989] | Topic 2.10, "conv—Conversions and Overflow" |
[UNIX 1992] | System V Interface Definition (SVID3) |
...