# Unit in the last place

(Redirected from Unit in the Last Place)

In computer science and numerical analysis, unit in the last place or unit of least precision (ULP) is the spacing between floating-point numbers, i.e., the value the least significant digit represents if it is 1. It is used as a measure of accuracy in numeric calculations.[1]

## Definition

In radix b, if x has exponent E, then ULP(x) = machine epsilon · bE,[2] but alternative definitions exist in the numerics and computing literature for ULP, exponent and machine epsilon, and they may give different equalities.[citation needed]

Another definition, suggested by John Harrison, is slightly different: ULP(x) is the distance between the two closest straddling floating-point numbers a and b (i.e., those with axb and ab), assuming that the exponent range is not upper-bounded.[3][4] These definitions differ only at signed powers of the radix.[citation needed]

The IEEE 754 specification—followed by all modern floating-point hardware—requires that the result of an elementary arithmetic operation (addition, subtraction, multiplication, division, and square root since 1985, and FMA since 2008) be correctly rounded, which implies that in rounding to nearest, the rounded result is within 0.5 ULP of the mathematically exact result, using John Harrison's definition; conversely, this property implies that the distance between the rounded result and the mathematically exact result is minimized (but for the halfway cases, it is satisfied by two consecutive floating-point numbers). Reputable numeric libraries compute the basic transcendental functions to between 0.5 and about 1 ULP. Only a few libraries compute them within 0.5 ULP, this problem being complex due to the Table-Maker's Dilemma.[5]

## Examples

### Example 1

Let x be a nonnegative floating-point number and assume that the active rounding attribute is round to nearest, ties to even, denoted RN. If ULP(x) is less than or equal to 1, then RN(x + 1) > x. Otherwise, RN(x + 1) = x or RN(x + 1) = x + ULP(x), depending on the value of the least significant digit and the exponent of x. This is demonstrated in the following Haskell code typed at an interactive prompt:[citation needed]

```> until (\x -> x == x+1) (+1) 0 :: Float
1.6777216e7
> it-1
1.6777215e7
> it+1
1.6777216e7
```

Here we start with 0 in 32-bit single-precision and repeatedly add 1 until the operation is idempotent. The result is equal to 224 since the significand for a single-precision number in this example contains 24 bits.[citation needed]

### Example 2

The following example in Java approximates π as a floating point value by finding the two double values bracketing π:

p0 < π < p1
```// π with 20 decimal digits
BigDecimal π = new BigDecimal("3.14159265358979323846");

// truncate to a double floating point
double p0 = π.doubleValue();
// -> 3.141592653589793  (hex: 0x1.921fb54442d18p1)

// p0 is smaller than π, so find next number representable as double
double p1 = Math.nextUp(p0);
// -> 3.1415926535897936 (hex: 0x1.921fb54442d19p1)
```

Then ULP(π) is determined as

ULP(π) = p1 - p0
```// ulp(π) is the difference between p1 and p0
BigDecimal ulp = new BigDecimal(p1).subtract(new BigDecimal(p0));
// -> 4.44089209850062616169452667236328125E-16
// (this is precisely 2**(-51))

// same result when using the standard library function
double ulpMath = Math.ulp(p0);
// -> 4.440892098500626E-16 (hex: 0x1.0p-51)
```

### Example 3

Another example, in Python, also typed at an interactive prompt, is:[citation needed]

```>>> x = 1.0
>>> p = 0
>>> while x != x + 1:
...   x = x * 2
...   p = p + 1
...
>>> x
9007199254740992.0
>>> p
53
>>> x + 2 + 1
9007199254740996.0
```

In this case, we start with x = 1 and repeatedly double it until x = x + 1. The result is 253, because the double-precision floating-point format uses a 53-bit significand.[citation needed]

## Language support

Since Java 1.5, the Java standard library has included `Math.ulp(double)` and `Math.ulp(float)` functions.

The C language library provides functions to calculate the next floating-point number in some given direction: `nextafterf` and `nexttowardf` for `float`, `nextafter` and `nexttoward` for `double`, `nextafterl` and `nexttowardl` for `long double`, declared in `<math.h>`.[6]

The Boost C++ Libraries offer boost::math::float_next, boost::math::float_prior, boost::math::nextafter and boost::math::float_advance functions to obtain nearby (and distant) floating-point values, [7] and boost::math::float_distance(a, b) to calculate the floating-point distance between two doubles. [8]