【问题标题】:Rounding numbers - What's wrong here?四舍五入 - 这里有什么问题?
【发布时间】:2014-02-04 15:15:18
【问题描述】:
  1. 我有 K 个浮点数列表,来自之前的一些计算,例如:

    K = numpy.arange(0.01, 0.3, 0.01)
    K =  [0.01, .... 0.28999999999999998, 0.29999999999999999]
    
  2. 现在,让我们将这些数字四舍五入到小数点后第二位:

    K_rounded_2  = [ round(kk, 2) for kk in K ]
    

    给:

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

现在,如果我要手动输入 K 作为列表,只需编写每个元素:

K = [ enter value 1, enter value 2, ...]

然后做:

K_rounded_2  = [ round(kk, 2) for kk in K ]

那么结果如预期:

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

那么在某些计算提供的列表和简单输入的列表之间有不同的处理方式吗?为什么 ?

【问题讨论】:

  • 如果不查看您之前的计算,就无法重现此情况。您可以编辑您的问题以包括这些吗?也包括实际的舍入代码。
  • @Wolf:我认为如何获得这些值并不重要。我猜问题出在其他地方。
  • @TimPietzcker 我同意

标签: python numpy python-3.3 rounding


【解决方案1】:

这种差异是因为在第一种情况下结果包含np.float64s,而当您直接输入数字时,您使用的是python的内置float 它具有更智能的字符串表示 em>:

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]

现在如果我们检查这些列表中元素的类型:

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)

但是代表的数字是一样的!

In [12]: rounded_a[0] == rounded_b[0]
Out[12]: True
In [13]: rounded_a[-1] == rounded_b[-1]
Out[13]: True

printed 的值是不同的,因为 python 内置的浮点数更智能,并且显示更短的文字来表示给定的浮点数 (参见python的3.1 What's new文档和相关的issue1580):

In [15]: 0.28999999999999998
Out[15]: 0.29

Numpy 确实这样做了,而是只输出“表示的原始/实际浮点数”。但请注意,结果是相同的,只是显示方式不同不同,尽管方式相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    相关资源
    最近更新 更多