Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
1d180684
Commit
1d180684
authored
Jun 28, 2009
by
Raymond Hettinger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Clean-up floating point tutorial.
parent
e9eb7b65
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
28 additions
and
23 deletions
+28
-23
Doc/tutorial/floatingpoint.rst
Doc/tutorial/floatingpoint.rst
+28
-23
No files found.
Doc/tutorial/floatingpoint.rst
View file @
1d180684
...
@@ -50,7 +50,7 @@ decimal value 0.1 cannot be represented exactly as a base 2 fraction. In base
...
@@ -50,7 +50,7 @@ decimal value 0.1 cannot be represented exactly as a base 2 fraction. In base
Stop at any finite number of bits, and you get an approximation. On most
Stop at any finite number of bits, and you get an approximation. On most
machines today, floats are approximated using a binary fraction with
machines today, floats are approximated using a binary fraction with
the numerator using the first 53 bits
following
the most significant bit and
the numerator using the first 53 bits
starting with
the most significant bit and
with the denominator as a power of two. In the case of 1/10, the binary fraction
with the denominator as a power of two. In the case of 1/10, the binary fraction
is ``3602879701896397 / 2 ** 55`` which is close to but not exactly
is ``3602879701896397 / 2 ** 55`` which is close to but not exactly
equal to the true value of 1/10.
equal to the true value of 1/10.
...
@@ -230,12 +230,8 @@ as ::
...
@@ -230,12 +230,8 @@ as ::
and recalling that *J* has exactly 53 bits (is ``>= 2**52`` but ``< 2**53``),
and recalling that *J* has exactly 53 bits (is ``>= 2**52`` but ``< 2**53``),
the best value for *N* is 56::
the best value for *N* is 56::
>>> 2**52
>>> 2**52 <= 2**56 // 10 < 2**53
4503599627370496
True
>>> 2**53
9007199254740992
>>> 2**56/10
7205759403792794.0
That is, 56 is the only value for *N* that leaves *J* with exactly 53 bits. The
That is, 56 is the only value for *N* that leaves *J* with exactly 53 bits. The
best possible value for *J* is then that quotient rounded::
best possible value for *J* is then that quotient rounded::
...
@@ -250,14 +246,13 @@ by rounding up::
...
@@ -250,14 +246,13 @@ by rounding up::
>>> q+1
>>> q+1
7205759403792794
7205759403792794
Therefore the best possible approximation to 1/10 in 754 double precision is
Therefore the best possible approximation to 1/10 in 754 double precision is::
that over 2\*\*56, or ::
7205759403792794 /
7205759403792793
6
7205759403792794 /
2 ** 5
6
Dividing both the numerator and denominator by two reduces the fraction to::
Dividing both the numerator and denominator by two reduces the fraction to::
3602879701896397 /
36028797018963968
3602879701896397 /
2 ** 55
Note that since we rounded up, this is actually a little bit larger than 1/10;
Note that since we rounded up, this is actually a little bit larger than 1/10;
if we had not rounded up, the quotient would have been a little bit smaller than
if we had not rounded up, the quotient would have been a little bit smaller than
...
@@ -269,24 +264,34 @@ above, the best 754 double approximation it can get::
...
@@ -269,24 +264,34 @@ above, the best 754 double approximation it can get::
>>> 0.1 * 2 ** 55
>>> 0.1 * 2 ** 55
3602879701896397.0
3602879701896397.0
If we multiply that fraction by 10\*\*
60, we can see the value of
out to
If we multiply that fraction by 10\*\*
55, we can see the value
out to
60
decimal digits::
55
decimal digits::
>>> 3602879701896397 * 10 **
60
// 2 ** 55
>>> 3602879701896397 * 10 **
55
// 2 ** 55
1000000000000000055511151231257827021181583404541015625
1000000000000000055511151231257827021181583404541015625
meaning that the exact number stored in the computer is approximately equal to
meaning that the exact number stored in the computer is equal to
the decimal value 0.100000000000000005551115123125. Rounding that to 17
the decimal value 0.1000000000000000055511151231257827021181583404541015625.
significant digits gives the 0.10000000000000001 that Python displays (well,
Instead of displaying the full decimal value, many languages (including
will display on any 754-conforming platform that does best-possible input and
older versions of Python), round the result to 17 significant digits::
output conversions in its C library --- yours may not!).
>>> format(0.1, '.17f')
'0.10000000000000001'
The :mod:`fractions` and :mod:`decimal` modules make these calculations
The :mod:`fractions` and :mod:`decimal` modules make these calculations
easy::
easy::
>>> from decimal import Decimal
>>> from decimal import Decimal
>>> from fractions import Fraction
>>> from fractions import Fraction
>>> print(Fraction.from_float(0.1))
3602879701896397/36028797018963968
>>> Fraction.from_float(0.1)
>>> print(Decimal.from_float(0.1))
Fraction(3602879701896397, 36028797018963968)
0.1000000000000000055511151231257827021181583404541015625
>>> (0.1).as_integer_ratio()
(3602879701896397, 36028797018963968)
>>> Decimal.from_float(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
>>> format(Decimal.from_float(0.1), '.17')
'0.10000000000000001'
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment