Floating point rounding modes in C++11

The standard C library has 4 floating point rounding modes available through cfenv.h. These are now available in C++11 through the header file cfenv.

  • The 4 floating point rounding modes are:
  • FE_TONEAREST rounds to the nearest integer. If the floating point value is exactly midway between two integers, then it does round half to even. The rest of the rounding modes are self explanatory.

  • None of the 4 rounding modes is equivalent to the round half away from zero which the round method does.

  • Anything to do with floating point operations is dependent on the FPU of the processor. So, the availability of these rounding modes and their values are highly dependent on the FPU of your processor.

  • On my x86_64 computer, all the 4 rounding modes were available and the values of these rounding modes were found to be:

#define FE_TONEAREST 0x000
#define FE_DOWNWARD 0x400
#define FE_UPWARD 0x800
#define FE_TOWARDZERO 0xC00
  • The FPU of your processor may support many other rounding modes in addition to these 4 modes.

  • On my x86_64 computer, I found that FE_TONEAREST was the default rounding mode when I used methods like rint and nearbyint to perform rounding.


C++: Mantissa and Exponent of Floating Point Number

The little-known frexp function from the C/C++ standard library can be used to extract the mantissa and exponent of a floating point number (float, double or long double):

#include <cmath>

const double d = 0.123;
int exponent;
const double mantissa = frexp( d, &exponent );

// Double:   0.123
// Mantissa: 0.984
// Exponent: -3

A few notes:

  • frexp assumes that a floating point number is represented as mantissa * 2 ^ exponent. This is a simple and convenient representation to work with. But, do keep in mind that this is not how the floating point number is actually stored.
  • For a positive floating point number, the mantissa returned by frexp always lies in the range [0.5, 1.0). This range is enough since a mantissa in the range (0.0, 0.5) can be converted to a value in [0.5, 1.0) by multiplying it by a suitable 2 ^ exponent. Note that the exponent can be negative or positive. The exception to this mantissa value is the floating point number 0.0, which is displayed as it is.
  • The mantissa and exponent returned by frexp are in no way related to the actual mantissa and exponent values stored in the floating point number format. For example, the IEEE-754 format uses a sign bit and modifies the exponent value using an exponent bias.