Substituting 0.1
for x
and displaying it on the console will display 0.1
.
x = 0.1
print(x)
# => 0.1
It seems obvious, but 0.1
cannot be accurately represented by floating point numbers (IEEE 754).
However, it is strange that 0.1
is displayed when print
is done.
I would like to write what I learned about this.
This article uses Python 3.7.
In this article, the term "floating point number" hereafter refers to "IEEE 754 double precision".
The floating-point number format is a number converted to the following format, with sign
, `ʻexp, and
frac`` arranged in that order.
(-1)^{sign} \times 2^{exp - 1023} \times (1 + frac \times 2^{-52})
The names and ranges of each symbol are as follows.
symbol | Japanese name | English name | range |
---|---|---|---|
sign | Code | sign | 0 or 1 |
exp | index | exponent | from 1 to 2,046 |
frac | mantissa | fraction | 0 to 4,503,599,627,370,495 |
See here for how to convert decimal numbers to this format. http://www.picfun.com/mathlib02.html
Here is an easy-to-understand way to convert a decimal decimal number to a binary decimal number. https://mathwords.net/syosuu2sin
Decimal decimals are often recurring decimals in decimal. [^ 1] In the process of converting a decimal decimal number to a binary number, if the operation is terminated at a finite digit, an error will occur with the number before conversion (rounding error).
[^ 1]: For example, of the numbers greater than 0 and less than 1 and represented within 3 decimal places (999), only 7 do not become recurring decimals when converted to binary. ..
Converts 0.1 to a floating point number. The following tools were used for the conversion. https://tools.m-bsys.com/calculators/ieee754.php
0.1
is the binary representation of floating point numbers
Code= 0
index= 01111111011
mantissa= 1001100110011001100110011001100110011001100110011010
When converted to decimal,
Code= 0
index= 1019
mantissa= 2702159776422298
is.
When applied to the floating point formula above,
\begin{align}
&(-1)^{0} \times 2^{1019-1023} \times (1 + 2702159776422298 \times 2^{-52})\\
&= 1 \times 2^{-4} \times (2^{52} \times 2^{-52} + 2702159776422298 \times 2^{-52})\\
&= 2^{-4} \times (4503599627370496 \times 2^{-52} + 2702159776422298 \times 2^{-52})\\
&= 2^{-4} \times 7205759403792794 \times 2^{-52}\\
&= 7205759403792794 \times 2^{-56}\\
&= \frac{7205759403792794}{72057594037927936}\\
&= 0.1000000000000000055511151231257827021181583404541015625
\end{align}
And 0.1 on the computer
0.1000000000000000055511151231257827021181583404541015625
You can see that it is treated as.
This is the reason why, for example, when you add 0.1
three times, it doesn't fit 0.3
(to be exact, it doesn't appear rather than "doesn't").
print(0.1 + 0.1 + 0.1)
# => 0.30000000000000004
Why is 0.1
displayed as 0.1
when print
is displayed even though 0.1
cannot be accurately represented by a floating point number, but on the official Python page The answer is written.
In old Python, prompts and repr () built-in functions picked and displayed decimal values such as 0.10000000000000001 with 17 significant digits. Starting with Python 3.1, most situations choose the shortest decimal value, such as 0.1. https://docs.python.org/ja/3/tutorial/floatingpoint.html
... apparently ...
In other words, the shortest floating-point number that has the same representation as 0.1
is selected. ~~ It seems that 0.1
is displayed as 0.1
in languages other than Python for the same reason. ~~ (Correction: For languages other than Python, please check the official documentation of each language)
Conversely, for example, if the number is very close to 0.1
, it will be displayed as 0.1
.
print(0.1000000000000000056)
# => 0.1
As far as I checked,
0.099999999999999998612221219218554324470460414886474609375
From
0.100000000000000012490009027033011079765856266021728515625
Up to is the range that is displayed as 0.1
when print
is done. This is because the numbers in this range are converted to the same floating point numbers as 0.1
.
Unless there is a particular shortest expression, it seems to display a number with 17 significant figures.
print(0.12345678901234567890)
#=> 0.12345678901234568
To specify the number of digits after the decimal point in Python: You can confirm that there is an error between the input value and the output.
print(f'{0.1:.20f}')
# => 0.10000000000000000555
Now,
This is the reason why, for example, when you add
0.1
three times, it doesn't fit0.3
(to be exact, it doesn't appear rather than "doesn't").
print(0.1 + 0.1 + 0.1)
# => 0.30000000000000004
I wrote.
In the case of a floating point number of 0.1
expressed in decimal, 5
appears for the first time in the 18th digit, but when 0.1
is added 3 times, 4
appears in the 17th digit.
This does not fit the calculation.
The following article explained this phenomenon.
-The floating point number of 0.1 is larger than 0.1, but why is it smaller than 1.0 when added 10 times [Part 1] -The floating point number of 0.1 is larger than 0.1, but why is it smaller than 1.0 when added 10 times? [Part 2]
Recommended Posts