Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Floating-Point Representation Distance (ULP), and Finding Adjacent Floating-Point Values

Finding the Next Representable Value in a Specific Direction (nextafter)
Finding the Next Greater Representable Value (float_next)
Finding the Next Smaller Representable Value (float_prior)
Calculating the Representation Distance Between Two floating-point Values (ULP) float_distance
Advancing a floating-point Value by a Specific Representation Distance (ULP) float_advance
Obtaining the Size of a Unit In the Last Place - ULP

Unit of Least Precision or Unit in the Last Place is the gap between two different, but as close as possible, floating-point numbers.

Most decimal values, for example 0.1, cannot be exactly represented as floating-point values, but will be stored as the closest representable floating-point.

Functions are provided for finding adjacent greater and lesser floating-point values, and estimating the number of gaps between any two floating-point values.

The floating-point type (FPT) must have has a fixed number of bits in the representation. The number of bits may set at runtime, but must be the same for all numbers. For example, NTL::quad_float type (fixed 128-bit representation), NTL::RR type (arbitrary but fixed decimal digits, default 150) or Boost.Multiprecision cpp_dec_float andcpp_bin_float are fixed at runtime, but not a type that extends the representation to provide an exact representation for any number, for example XRC eXact Real in C.

The accuracy of mathematical functions can be assessed and displayed in terms of Unit in the Last Place, often as a ulps plot or by binning the differences as a histogram. Samples are evaluated using the implementation under test and compared with 'known good' representation obtained using a more accurate method. Other implementations, often using arbitrary precision arithmetic, for example Wolfram Alpha are one source of references values. The other method, used widely in Boost.Math special functions, it to carry out the same algorithm, but using a higher precision type, typically using Boost.Multiprecision types like cpp_bin_float_quad for 128-bit (about 35 decimal digit precision), or cpp_bin_float_50 (for 50 decimal digit precision).

When converted to a particular machine representation, say double, say using a static_cast, the value is the nearest representation possible for the double type. This value cannot be 'wrong' by more than half a Unit in the last place (ULP), and can be obtained using the Boost.Math function ulp. (Unless the algorithm is fundamentally flawed, something that should be revealed by 'sanity' checks using some independent sources).

See some discussion and example plots by Cleve Moler of Mathworks ulps plots reveal math-function accuracy.


PrevUpHomeNext