Unit in the last place
This article needs additional citations for verification. (March 2015) |
In
Definition
The most common definition is: In radix with precision , if , then ,[2] where is the minimal exponent of the normal numbers. In particular, for normal numbers, and for subnormals.
Another definition, suggested by John Harrison, is slightly different: is the distance between the two closest straddling floating-point numbers and (i.e., satisfying and ), assuming that the exponent range is not upper-bounded.[3][4] These definitions differ only at signed powers of the radix.[2]
The
Since the 2010s, advances in floating-point mathematics have allowed correctly rounded functions to be almost as fast in average as these earlier, less accurate functions. A correctly rounded function would also be fully reproducible. An earlier, intermediate milestone was the 0.501 ulp functions,[clarification needed] which theoretically would only produce one incorrect rounding out of 1000 random floating-point inputs.[6]
Examples
Example 1
Let be a positive floating-point number and assume that the active rounding mode is
> until (\x -> x == x+1) (+1) 0 :: Float
1.6777216e7
> it-1
1.6777215e7
> it+1
1.6777216e7
Here we start with 0 in single precision (binary32) and repeatedly add 1 until the operation does not change the value. Since the significand for a single-precision number contains 24 bits, the first integer that is not exactly representable is 224+1, and this value rounds to 224 in round to nearest, ties to even. Thus the result is equal to 224.
Example 2
The following example in Java approximates π as a floating point value by finding the two double values bracketing : .
// π 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 is determined as .
// 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:
>>> 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
. Similarly to Example 1, the result is 253 because the
Language support
The
boost::math::float_next
, boost::math::float_prior
, boost::math::nextafter
and boost::math::float_advance
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]
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>
. It also provides the macros FLT_EPSILON
, DBL_EPSILON
, LDBL_EPSILON
, which represent the positive difference between 1.0 and the next greater representable number in the corresponding type (i.e. the ulp of one).[9]
The
Math.ulp(double)
and Math.ulp(float)
The Swift standard library provides access to the next floating-point number in some given direction via the instance properties nextDown
and nextUp
. It also provides the instance property ulp
and the type property ulpOfOne
(which corresponds to C macros like FLT_EPSILON
[10]) for Swift's floating-point types.[11]
See also
- IEEE 754
- ISO/IEC 10967, part 1 requires an ulp function
- Least significant bit(LSB)
- Machine epsilon
- Round-off error
References
- ).
- ^ ISBN 978-3-319-76525-9.
- ^ Harrison, John. "A Machine-Checked Theory of Floating Point Arithmetic". Retrieved 17 July 2013.
- ^ Muller, Jean-Michel (2005–11). "On the definition of ulp(x)". INRIA Technical Report 5504. ACM Transactions on Mathematical Software, Vol. V, No. N, November 2005. Retrieved in 2012-03 from http://ljk.imag.fr/membres/Carine.Lucas/TPScilab/JMMuller/ulp-toms.pdf.
- ^ Kahan, William. "A Logarithm Too Clever by Half". Retrieved 14 November 2008.
- ^ Brisebarre, Nicolas; Hanrot, Guillaume; Muller, Jean-Michel; Zimmermann, Paul (May 2024). "Correctly-rounded evaluation of a function: why, how, and at what cost?".
- ^ Boost float_advance.
- ^ Boost float_distance.
- ^ ISO/IEC 9899:1999 specification (PDF). p. 237, §7.12.11.3 The nextafter functions and §7.12.11.4 The nexttoward functions.
- ^ "ulpOfOne - FloatingPoint | Apple Developer Documentation". Apple Inc. Apple Inc. Retrieved 18 August 2019.
- ^ "FloatingPoint - Swift Standard Library | Apple Developer Documentation". Apple Inc. Apple Inc. Retrieved 18 August 2019.
Bibliography
![](http://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Wiktionary-logo-en-v2.svg/40px-Wiktionary-logo-en-v2.svg.png)
- Goldberg, David (1991–03). "Rounding Error" in "What Every Computer Scientist Should Know About Floating-Point Arithmetic". Computing Surveys, ACM, March 1991. Retrieved from http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html#689.
- Muller, Jean-Michel (2010). Handbook of floating-point arithmetic. Boston: Birkhäuser. pp. 32–37. ISBN 978-0-8176-4704-9.