Reputation: 219
I have K a list of floats that comes from some previous calculation, such as:
K = numpy.arange(0.01, 0.3, 0.01)
K = [0.01, .... 0.28999999999999998, 0.29999999999999999]
Now, lets round those numbers to the 2nd decimal:
K_rounded_2 = [ round(kk, 2) for kk in K ]
Gives:
>>> K_rounded_2
[0.01, 0.02, 0.029999999999999999, 0.040000000000000001, 0.050000000000000003, 0.059999999999999998, 0.070000000000000007, 0.080000000000000002, 0.089999999999999997, 0.10000000000000001, 0.11, 0.12, 0.13, 0.14000000000000001, 0.14999999999999999, 0.16, 0.17000000000000001, 0.17999999999999999, 0.19, 0.20000000000000001, 0.20999999999999999, 0.22, 0.23000000000000001, 0.23999999999999999, 0.25, 0.26000000000000001, 0.27000000000000002, 0.28000000000000003, 0.28999999999999998, 0.29999999999999999]
Now, if i was to manually input K as a list, simply writing each element:
K = [ enter value 1, enter value 2, ...]
and then do:
K_rounded_2 = [ round(kk, 2) for kk in K ]
then the result is as expected:
>>> K_rounded_2
[0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3]
So there is a different treatment between the list that is provided by some calculation and the one that is simply input ? Why ?
Upvotes: 0
Views: 143
Reputation: 102029
This difference is due to the fact that in the first case the result contains np.float64
s while when you enter the numbers directly you are using python's built-in float
which has a smarter string representation:
In [1]: import numpy as np
In [2]: a = np.arange(0.01, 0.3, 0.01)
In [3]: a
Out[3]:
array([ 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09,
0.1 , 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18,
0.19, 0.2 , 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27,
0.28, 0.29])
In [4]: [round(elem, 2) for elem in a]
Out[4]:
[0.01,
0.02,
0.029999999999999999,
0.040000000000000001,
0.050000000000000003,
0.059999999999999998,
0.070000000000000007,
0.080000000000000002,
0.089999999999999997,
0.10000000000000001,
0.11,
0.12,
0.13,
0.14000000000000001,
0.14999999999999999,
0.16,
0.17000000000000001,
0.17999999999999999,
0.19,
0.20000000000000001,
0.20999999999999999,
0.22,
0.23000000000000001,
0.23999999999999999,
0.25,
0.26000000000000001,
0.27000000000000002,
0.28000000000000003,
0.28999999999999998]
In [5]: b = [0.01,
...: 0.02,
...: 0.029999999999999999,
...: 0.040000000000000001,
...: 0.050000000000000003,
...: 0.059999999999999998,
...: 0.070000000000000007,
...: 0.080000000000000002,
...: 0.089999999999999997,
...: 0.10000000000000001,
...: 0.11,
...: 0.12,
...: 0.13,
...: 0.14000000000000001,
...: 0.14999999999999999,
...: 0.16,
...: 0.17000000000000001,
...: 0.17999999999999999,
...: 0.19,
...: 0.20000000000000001,
...: 0.20999999999999999,
...: 0.22,
...: 0.23000000000000001,
...: 0.23999999999999999,
...: 0.25,
...: 0.26000000000000001,
...: 0.27000000000000002,
...: 0.28000000000000003,
...: 0.28999999999999998]
In [6]: [round(elem, 2) for elem in b]
Out[6]:
[0.01,
0.02,
0.03,
0.04,
0.05,
0.06,
0.07,
0.08,
0.09,
0.1,
0.11,
0.12,
0.13,
0.14,
0.15,
0.16,
0.17,
0.18,
0.19,
0.2,
0.21,
0.22,
0.23,
0.24,
0.25,
0.26,
0.27,
0.28,
0.29]
Now if we check the types of the elements of these lists:
In [10]: rounded_a = [round(elem, 2) for elem in a]
...: rounded_b = [round(elem, 2) for elem in b]
...:
In [11]: type(rounded_a[0]), type(rounded_b[0])
Out[11]: (numpy.float64, builtins.float)
However the numbers represented are the same!
In [12]: rounded_a[0] == rounded_b[0]
Out[12]: True
In [13]: rounded_a[-1] == rounded_b[-1]
Out[13]: True
The printed value is different because python built-in floats are smarter and display the shorter literal that would represent the given floating-point number (see python's 3.1 What's new document and associated issue1580):
In [15]: 0.28999999999999998
Out[15]: 0.29
Numpy does do this and instead just outputs the "raw/actual floating-point number represented". But notice that the result is the same, it is only displayed differently, although in an equivalent way.
Upvotes: 3