| Home | Libraries | People | FAQ | More

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

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.