Jump to content

Unit in the last place: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
m Task 70: Update syntaxhighlight tags - remove use of deprecated <source> tags
→‎Definition: correction + {{Clarify}}
 
(42 intermediate revisions by 15 users not shown)
Line 1: Line 1:
{{Short description|Floating-point accuracy metric}}
{{refimprove|date=March 2015}}
{{more citations needed|date=March 2015}}
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 [[Numerical digit|digit]] (rightmost digit) represents if it is 1. It is used as a measure of [[Accuracy and precision|accuracy]] in numeric calculations.<ref>David Goldberg: What Every Computer Scientist Should Know About Floating-Point Arithmetic, section 1.2 Relative Error and Ulps, ACM Computing Surveys, Vol 23, No 1, pp.8, March 1991.</ref>
{{Use dmy dates|date=July 2021}}
In [[computer science]] and [[numerical analysis]], '''unit in the last place''' or '''unit of least precision''' ('''ulp''') is the spacing between two consecutive [[floating-point]] numbers, i.e., the value the ''[[least significant digit]]'' (rightmost digit) represents if it is 1.<!-- Strictly speaking, when dealing with the representation, it needs to be normalized (e.g. in IEEE 754 decimal arithmetic); but perhaps this would be too much detailed for the LEDE. --> It is used as a measure of [[Accuracy and precision|accuracy]] in numeric calculations.<ref>{{cite journal |author-first=David |author-last=Goldberg |title=What Every Computer Scientist Should Know About Floating-Point Arithmetic |journal=[[ACM Computing Surveys]] |date=March 1991 |volume=23 |issue=1 |pages=5–48 |doi=10.1145/103162.103163 |doi-access=free|s2cid=222008826 |url=http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf |archive-url=https://web.archive.org/web/20060720140912/http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf |archive-date=2006-07-20 |url-status=live |access-date=2016-01-20}} ([http://www.validlab.com/goldberg/paper.pdf], [http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html], [http://www.cse.msu.edu/~cse320/Documents/FloatingPoint.pdf]).</ref>


==Definition==
==Definition==
One definition is: In [[radix]] ''b'' with precision ''p'', if ''b''<sup>''e''</sup> |''x''| < ''b''<sup>''e''+1</sup>, then ULP(''x'') = ''b''<sup>max(''e'',''e''<sub>min</sub>)−''p''+1</sup>.<ref name="hfpa2018">{{cite book |author-last1=Muller |author-first1=Jean-Michel |author-last2=Brunie |author-first2=Nicolas |author-last3=de Dinechin |author-first3=Florent |author-last4=Jeannerod |author-first4=Claude-Pierre |author-first5=Mioara |author-last5=Joldes |author-last6=Lefèvre |author-first6=Vincent |author-last7=Melquiond |author-first7=Guillaume |author-last8=Revol |author-first8=Nathalie |author-last9=Torres |author-first9=Serge |title=Handbook of Floating-Point Arithmetic |date=2018 |orig-year=2010 |publisher=[[Birkhäuser]] |edition=2 |isbn=978-3-319-76525-9 |doi=10.1007/978-3-319-76526-6}}</ref>
The most common definition is: In [[radix]] <math>b</math> with precision <math>p</math>, if <math>b^e \le |x| < b^{e+1}</math>, then {{nowrap|<math>\operatorname{ulp}(x) = b^{\max \{ e, \, e_\min \} - p + 1}</math>,<ref name="hfpa2018">{{cite book |author-last1=Muller |author-first1=Jean-Michel |author-last2=Brunie |author-first2=Nicolas |author-last3=de Dinechin |author-first3=Florent |author-last4=Jeannerod |author-first4=Claude-Pierre |author-first5=Mioara |author-last5=Joldes |author-last6=Lefèvre |author-first6=Vincent |author-last7=Melquiond |author-first7=Guillaume |author-last8=Revol |author-first8=Nathalie|author8-link=Nathalie Revol |author-last9=Torres |author-first9=Serge |title=Handbook of Floating-Point Arithmetic |date=2018 |orig-year=2010 |publisher=[[Birkhäuser]] |edition=2 |isbn=978-3-319-76525-9 |doi=10.1007/978-3-319-76526-6}}</ref>}} where <math>e_\min</math> is the minimal exponent of the normal numbers. In particular, <math>\operatorname{ulp}(x) = b^{e - p + 1}</math> for [[Normal number (computing)|normal numbers]], and <math>\operatorname{ulp}(x) = b^{e_\min - p + 1}</math> for [[Subnormal number|subnormals]].
<!-- TODO: Say something about ulp(0), not defined above. See what the sources (books, programming languages, libraries) say... But note that some documents use a definition for their own purpose, for practical reasons; this should not be regarded as a standard definition. -->


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 ''a'' ''x'' ''b'' and ''a'' ''b''), assuming that the exponent range is not upper-bounded.<ref>{{cite web|last=Harrison|first=John|title=A Machine-Checked Theory of Floating Point Arithmetic|url=http://www.cl.cam.ac.uk/~jrh13/papers/fparith.html|accessdate=2013-07-17}}</ref><ref>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.</ref> These definitions differ only at signed powers of the radix.<ref name="hfpa2018"/>
Another definition, suggested by John Harrison, is slightly different: <math>\operatorname{ulp}(x)</math> is the distance between the two closest ''straddling'' floating-point numbers <math>a</math> and <math>b</math> (i.e., satisfying <math>a \le x \le b</math> and <math>a \neq b</math>), assuming that the exponent range is not upper-bounded.<ref>{{cite web|last=Harrison|first=John|title=A Machine-Checked Theory of Floating Point Arithmetic|url=https://www.cl.cam.ac.uk/~jrh13/papers/fparith.html|access-date=2013-07-17}}</ref><ref>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.</ref> These definitions differ only at signed powers of the radix.<ref name="hfpa2018"/>


The [[IEEE 754]] specification&mdash;followed by all modern floating-point hardware&mdash;requires that the result of an [[elementary arithmetic]] operation (addition, subtraction, multiplication, division, and [[square root]] since 1985, and [[Fused multiply–add|FMA]] since 2008) be [[Rounding#Table-maker's dilemma|correctly rounded]]<!-- The current link for correct rounding is under "Table-maker's dilemma" though these elementary arithmetic operations are not concerned by the TMD in practice. -->, 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 [[numerical analysis|numeric]] [[library (computing)|libraries]] compute the basic [[transcendental function]]s 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]].<ref>{{cite web |last=Kahan |first=William |title=A Logarithm Too Clever by Half |url=http://www.cs.berkeley.edu/~wkahan/LOG10HAF.TXT |accessdate=2008-11-14}}</ref>
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 [[Fused multiply–add|FMA]] since 2008) be correctly [[Rounding#Floating-point rounding|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 [[numerical analysis|numeric]] [[library (computing)|libraries]] compute the basic [[transcendental function]]s 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]].<ref>{{cite web |last=Kahan |first=William |title=A Logarithm Too Clever by Half |url=https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT |access-date=2008-11-14}}</ref>

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. {{Clarify|date=June 2024|reason=It seems that 0.501 ulp is just an example, not really an earlier, intermediate milestone. |text=An earlier, intermediate milestone was the 0.501 ulp functions,}} which theoretically would only produce one incorrect rounding out of 1000 random floating-point inputs.<ref>{{cite web |last1=Brisebarre |first1=Nicolas |last2=Hanrot |first2=Guillaume |last3=Muller |first3=Jean-Michel |last4=Zimmermann |first4=Paul |title=Correctly-rounded evaluation of a function: why, how, and at what cost? |url=https://hal.science/hal-04474530 |date=May 2024}}</ref>


==Examples==
==Examples==
===Example 1===
===Example 1===
Let ''x'' be a positive floating-point number and assume that the active rounding attribute is [[IEEE floating point#Roundings to nearest|round to nearest, ties to even]], denoted RN. If ULP(''x'') is less than or equal to 1, then {{mono|1=RN(''x''&nbsp;+&nbsp;1)&nbsp;>&nbsp;''x''}}. Otherwise, {{mono|1=RN(''x''&nbsp;+&nbsp;1)&nbsp;=&nbsp;''x''}} or {{mono|1=RN(''x''&nbsp;+&nbsp;1)&nbsp;=&nbsp;''x''&nbsp;+&nbsp;ULP(x)}}, depending on the value of the least significant digit and the exponent of x. This is demonstrated in the following [[Haskell (programming language)|Haskell]] code typed at an interactive prompt:{{fact|date=March 2015}}
Let <math>x</math> be a positive floating-point number and assume that the active rounding mode is [[IEEE floating point#Roundings to nearest|round to nearest, ties to even]], denoted <math>\operatorname{RN}</math>. If <math>\operatorname{ulp}(x) \le 1</math>, then <math>\operatorname{RN} (x + 1) > x</math>. Otherwise, <math>\operatorname{RN} (x + 1) = x</math> or <math>\operatorname{RN} (x + 1) = x + \operatorname{ulp}(x)</math>, depending on the value of the least significant digit and the exponent of <math>x</math>. This is demonstrated in the following [[Haskell (programming language)|Haskell]] code typed at an interactive prompt:{{citation needed|date=March 2015}}


<syntaxhighlight lang="lhaskell">
<syntaxhighlight lang="lhaskell">
Line 22: Line 27:
</syntaxhighlight>
</syntaxhighlight>


Here we start with 0 in [[Single-precision floating-point format|single precision]] 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 2<sup>24</sup>+1, and this value rounds to 2<sup>24</sup> in round to nearest, ties to even. Thus the result is equal to 2<sup>24</sup>.
Here we start with 0 in [[Single-precision floating-point format|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 2<sup>24</sup>+1, and this value rounds to 2<sup>24</sup> in round to nearest, ties to even. Thus the result is equal to 2<sup>24</sup>.


===Example 2===
===Example 2===
The following example in [[Java (programming language)|Java]] approximates [[Pi|{{pi}}]] as a floating point value by finding the two double values bracketing {{pi}}:
The following example in [[Java (programming language)|Java]] approximates [[Pi|{{pi}}]] as a floating point value by finding the two double values bracketing <math>\pi</math>: <math>p_0 < \pi < p_1</math>.
:{{math|''p''<sub>0</sub> < &pi; < ''p''<sub>1</sub>}}
<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
// π with 20 decimal digits
// π with 20 decimal digits
Line 40: Line 44:
</syntaxhighlight>
</syntaxhighlight>


Then {{math|ULP(&pi;)}} is determined as
Then <math>\operatorname{ulp}(\pi)</math> is determined as <math>\operatorname{ulp}(\pi) = p_1 - p_0</math>.
:{{math|ULP(&pi;) {{=}} ''p''<sub>1</sub> - ''p''<sub>0</sub>}}
<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
// ulp(π) is the difference between p1 and p0
// ulp(π) is the difference between p1 and p0
Line 55: Line 58:
===Example 3===
===Example 3===


Another example, in [[Python (programming language)|Python]], also typed at an interactive prompt, is:{{fact|date=March 2015}}
Another example, in [[Python (programming language)|Python]], also typed at an interactive prompt, is:


<syntaxhighlight lang="pycon">
<syntaxhighlight lang="pycon">
Line 72: Line 75:
</syntaxhighlight>
</syntaxhighlight>


In this case, we start with {{mono|1=''x''&nbsp;=&nbsp;1}} and repeatedly double it until {{mono|1=''x''&nbsp;=&nbsp;''x''&nbsp;+&nbsp;1}}. Similarly to Example&nbsp;1, the result is 2<sup>53</sup> because the [[double-precision]] floating-point format uses a 53-bit significand.
In this case, we start with <code>x = 1</code> and repeatedly double it until <code>x = x + 1</code>. Similarly to Example&nbsp;1, the result is 2<sup>53</sup> because the [[double-precision]] floating-point format uses a 53-bit significand.


==Language support==
==Language support==
The [[Boost C++ libraries]] provides the functions <code>boost::math::float_next</code>, <code>boost::math::float_prior</code>, <code>boost::math::nextafter</code>
The [[Boost C++ libraries]] provides the functions <code>boost::math::float_next</code>, <code>boost::math::float_prior</code>, <code>boost::math::nextafter</code>
and <code>boost::math::float_advance</code> to obtain nearby (and distant) floating-point values,<ref name="Boost advance">{{cite book | url=http://www.boost.org/doc/libs/release/libs/math/doc/html/math_toolkit/next_float/float_advance.html | title=Boost float_advance}}</ref> and <code>boost::math::float_distance(a, b)</code> to calculate the floating-point distance between two doubles.<ref name="Boost float_distance">{{cite book | url=http://www.boost.org/doc/libs/release/libs/math/doc/html/math_toolkit/next_float/float_distance.html | title=Boost float_distance}}</ref>
and <code>boost::math::float_advance</code> to obtain nearby (and distant) floating-point values,<ref name="Boost advance">{{cite book | url=https://www.boost.org/doc/libs/release/libs/math/doc/html/math_toolkit/next_float/float_advance.html | title=Boost float_advance}}</ref> and <code>boost::math::float_distance(a, b)</code> to calculate the floating-point distance between two doubles.<ref name="Boost float_distance">{{cite book | url=https://www.boost.org/doc/libs/release/libs/math/doc/html/math_toolkit/next_float/float_distance.html | title=Boost float_distance}}</ref>


The [[C (programming language)|C language]] library provides functions to calculate the next floating-point number in some given direction: <code>nextafterf</code> and <code>nexttowardf</code> for <code>float</code>, <code>nextafter</code> and <code>nexttoward</code> for <code>double</code>, <code>nextafterl</code> and <code>nexttowardl</code> for <code>long double</code>, declared in <code><math.h></code>. It also provides the macros <code>FLT_EPSILON</code>, <code>DBL_EPSILON</code>, <code>LDBL_EPSILON</code>, which represent the positive difference between 1.0 and the next greater representable number in the corresponding type (i.e. the ULP of one).<ref name=c99>{{cite book | url=http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf | title=ISO/IEC 9899:1999 specification | at=p. 237, §7.12.11.3 ''The nextafter functions'' and §7.12.11.4 ''The nexttoward functions''}}</ref>
The [[C (programming language)|C language]] library provides functions to calculate the next floating-point number in some given direction: <code>nextafterf</code> and <code>nexttowardf</code> for <code>float</code>, <code>nextafter</code> and <code>nexttoward</code> for <code>double</code>, <code>nextafterl</code> and <code>nexttowardl</code> for <code>long double</code>, declared in <code><math.h></code>. It also provides the macros <code>FLT_EPSILON</code>, <code>DBL_EPSILON</code>, <code>LDBL_EPSILON</code>, which represent the positive difference between 1.0 and the next greater representable number in the corresponding type (i.e. the ulp of one).<ref name=c99>{{cite book | url=https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf | title=ISO/IEC 9899:1999 specification | at=p. 237, §7.12.11.3 ''The nextafter functions'' and §7.12.11.4 ''The nexttoward functions''}}</ref>


The [[Java (language)|Java]] standard library provides the functions {{Javadoc:SE|java/lang|Math|ulp(double)}} and {{Javadoc:SE|java/lang|Math|ulp(float)}}. They were introduced with Java 1.5.
The [[Java (language)|Java]] standard library provides the functions {{Javadoc:SE|java/lang|Math|ulp(double)}} and {{Javadoc:SE|java/lang|Math|ulp(float)}}. They were introduced with Java 1.5.


The [[Swift (programming language)|Swift]] standard library provides access to the next floating-point number in some given direction via the instance properties <code>nextDown</code> and <code>nextUp</code>. It also provides the instance property <code>ulp</code> and the type property <code>ulpOfOne</code> (which corresponds to C macros like <code>FLT_EPSILON</code><ref>{{cite web | url=https://developer.apple.com/documentation/swift/floatingpoint/3017999-ulpofone | title=ulpOfOne - FloatingPoint &#124; Apple Developer Documentation | website=Apple Inc. | publisher=Apple Inc. | access-date=2019-08-18}}</ref>) for Swift's floating-point types.<ref>{{cite web | url=https://developer.apple.com/documentation/swift/floatingpoint | title=FloatingPoint - Swift Standard Library &#124; Apple Developer Documentation | website=Apple Inc. | publisher=Apple Inc. | access-date=2019-08-18}}</ref>
The [[Swift (programming language)|Swift]] standard library provides access to the next floating-point number in some given direction via the instance properties <code>nextDown</code> and <code>nextUp</code>. It also provides the instance property <code>ulp</code> and the type property <code>ulpOfOne</code> (which corresponds to C macros like <code>FLT_EPSILON</code><ref>{{cite web | url=https://developer.apple.com/documentation/swift/floatingpoint/ulpofone-7hdlb | title=ulpOfOne - FloatingPoint {{pipe}} Apple Developer Documentation | website=Apple Inc. | publisher=Apple Inc. | access-date=2019-08-18}}</ref>) for Swift's floating-point types.<ref>{{cite web | url=https://developer.apple.com/documentation/swift/floatingpoint | title=FloatingPoint - Swift Standard Library {{pipe}} Apple Developer Documentation | website=Apple Inc. | publisher=Apple Inc. | access-date=2019-08-18}}</ref>


==See also==
==See also==
Line 89: Line 92:
* [[Least significant bit]] (LSB)
* [[Least significant bit]] (LSB)
* [[Machine epsilon]]
* [[Machine epsilon]]
* [[Round-off error]]


==References==
==References==
Line 96: Line 100:
{{Wiktionary|ulp}}
{{Wiktionary|ulp}}


*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.
*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.
*{{Cite book|title=Handbook of floating-point arithmetic|last=Muller|first=Jean-Michel|publisher=Birkhäuser|year=2010|isbn=978-0-8176-4704-9|location=Boston|pages=32-37}}
*{{Cite book|title=Handbook of floating-point arithmetic|last=Muller|first=Jean-Michel|publisher=Birkhäuser|year=2010|isbn=978-0-8176-4704-9|location=Boston|pages=32–37}}

{{use dmy dates|date=January 2012}}


[[Category:Computer arithmetic]]
[[Category:Computer arithmetic]]

Latest revision as of 09:42, 21 June 2024

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

Definition[edit]

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

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[edit]

Example 1[edit]

Let be a positive floating-point number and assume that the active rounding mode is round to nearest, ties to even, denoted . If , then . Otherwise, or , depending on the value of the least significant digit and the exponent of . 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 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[edit]

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[edit]

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 double-precision floating-point format uses a 53-bit significand.

Language support[edit]

The Boost C++ libraries provides the functions 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 Java standard library provides the functions Math.ulp(double) and Math.ulp(float). They were introduced with Java 1.5.

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[edit]

References[edit]

  1. ^ Goldberg, David (March 1991). "What Every Computer Scientist Should Know About Floating-Point Arithmetic" (PDF). ACM Computing Surveys. 23 (1): 5–48. doi:10.1145/103162.103163. S2CID 222008826. Archived (PDF) from the original on 20 July 2006. Retrieved 20 January 2016. ([1], [2], [3]).
  2. ^ a b Muller, Jean-Michel; Brunie, Nicolas; de Dinechin, Florent; Jeannerod, Claude-Pierre; Joldes, Mioara; Lefèvre, Vincent; Melquiond, Guillaume; Revol, Nathalie; Torres, Serge (2018) [2010]. Handbook of Floating-Point Arithmetic (2 ed.). Birkhäuser. doi:10.1007/978-3-319-76526-6. ISBN 978-3-319-76525-9.
  3. ^ Harrison, John. "A Machine-Checked Theory of Floating Point Arithmetic". Retrieved 17 July 2013.
  4. ^ 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.
  5. ^ Kahan, William. "A Logarithm Too Clever by Half". Retrieved 14 November 2008.
  6. ^ Brisebarre, Nicolas; Hanrot, Guillaume; Muller, Jean-Michel; Zimmermann, Paul (May 2024). "Correctly-rounded evaluation of a function: why, how, and at what cost?".
  7. ^ Boost float_advance.
  8. ^ Boost float_distance.
  9. ^ ISO/IEC 9899:1999 specification (PDF). p. 237, §7.12.11.3 The nextafter functions and §7.12.11.4 The nexttoward functions.
  10. ^ "ulpOfOne - FloatingPoint | Apple Developer Documentation". Apple Inc. Apple Inc. Retrieved 18 August 2019.
  11. ^ "FloatingPoint - Swift Standard Library | Apple Developer Documentation". Apple Inc. Apple Inc. Retrieved 18 August 2019.

Bibliography[edit]