Document: WG14 N1504

Fix for DR 301 (Meaning of FE_* macros in <fenv.h>)


Submitter: Fred J. Tydeman (USA)
Submission Date: 2010-06-17
Subject: Fix for DR 301 (Meaning of FE_* macros in <fenv.h>)

Defect Report 301 was answered (in part) as not really a defect, but a deficiency which could be addressed in a future revision of the C Standard. The material could be added as Recommended Practice.

The problem being addressed is: what is the meaning of the FE_* macros for environments that are not IEEE-754 (IEC 60559)?

Since this is being added as recommended practice, it should have no affect on existing implementations.

Add to paragraph 8 [the one about FLT_ROUNDS] in 5.2.4.2.2 Characteristics of floating types <float.h>:

See 7.6 Floating-point environment paragraph 8 for meaning of these rounding modes.

Add a new paragraph to 7.6 Floating-point environment <fenv.h> after paragraph 6 (the one that mentions FE_DIVBYZERO through FE_UNDERFLOW):

Recommended practice

These status flags should be set as side-effects of floating-point operations.

FE_INVALID should be a side-effect of:


FE_DIVBYZERO should be a side-effect of dividing a non-zero finite number by zero, e.g., 1.0/0.0. There should be no exception when dividing an infinity by zero, nor when dividing a NaN by zero.

It is unspecified as to whether FE_INVALID, FE_DIVBYZERO, or no exception is raised for zero / zero.

FE_OVERFLOW should be a side-effect of producing a rounded floating-point result (assuming an unbounded exponent range) larger in magnitude than the largest finite number.

FE_UNDERFLOW should be a side-effect of producing a rounded floating-point result (assuming an unbounded exponent range) smaller in magnitude than the smallest non-zero finite number, or an inexact subnormal number smaller than the smallest non-zero normalized number.

FE_INEXACT should be a side-effect of producing a rounded floating-point result that differs from the mathematical (or infinitely precise) result.

Add a new paragraph to 7.6 Floating-point environment <fenv.h> after paragraph 8 (the one that mentions FE_DOWNWARD through FE_UPWARD):

Recommended practice

These control modes should affect result values of floating-point operations.

FE_TOWARDZERO means the result should be the format's value closest to and no greater in magnitude than the infinitely precise result. For example, if rounding to integer value in floating-point format, +3.7 rounds to +3.0 and -3.7 rounds to -3.0.

FE_UPWARD means the result should be the format's value closest to and no less than the infinitely precise result. For example, if rounding to integer value in floating-point format, +3.1 rounds to +4.0 and -3.7 rounds to -3.0.

FE_DOWNWARD means the result should be the format's value closest to and no greater than the infinitely precise result. For example, if rounding to integer value in floating-point format, +3.7 rounds to +3.0 and -3.1 rounds to -4.0.

FE_TONEAREST means the result should be the format's value closest to the infinitely precise result. It is unspecified as to what happens when the two nearest representable values are equally near. For example, if rounding to integer value in floating-point format, +3.1 rounds to +3.0 and +3.7 rounds to +4.0, and +3.5 rounds to either +3.0 or +4.0.

Add to the Rationale on fenv.h

The FE_* macros are given meaning via recommended practice as there is no universal agreement on their meaning in all cases and some implementations do different things for some cases (such as 0.0/0.0).

Update DR 301 to point to this document.