...one of the most highly
regarded and expertly designed C++ library projects in the
world.

— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards

- 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.