Python 3舍入问题

时间:2016-02-19 17:09:13

标签: python-3.x rounding

为什么下面的舍入在python 3中不起作用,只在python 2中起作用?

random_nums = np.array([-1, 0, 1, 2, 3])
probabilities = np.array([0.01, 0.3, 0.58, 0.1, 0.01])
target = dict(zip(random_nums, probabilities))
target = {k: round(v, 2) for k, v in target.items()}

out:
{-1: 0.01,
 0: 0.29999999999999999,
 1: 0.57999999999999996,
 2: 0.10000000000000001,
 3: 0.01}

2 个答案:

答案 0 :(得分:4)

您正在使用NumPy float64个对象而不是Python float个对象。这有一些后果:

  1. 在Python 3中,float64个对象使用NumPy的舍入代码而不是Python来舍入。 Python float的舍入代码总是给出正确的舍入结果。 NumPy的舍入代码没有。 (在Python 2中,它不可能覆盖自定义类型的round操作,因此当您在Python 2中对float64对象进行舍入时,它首先会转换为Python {{1}然后,Python的舍入代码用于给出float结果。这是您在Python 2和Python 3之间看到差异的主要原因。)

    < / LI>
  2. 再次在Python 3上,由于上​​述原因,float上的round会产生float64结果。在Python 2上,float64对象上的round会产生float64结果。

  3. Python float对象具有不同的float,这将提供愉快的输出。特别是,Python的repr保证往返(不是太大,不是太小)十进制值,最多15个有效数字:repr的表示为0.58,例如。 NumPy '0.58'对象的表示没有此属性:它只是根据存储值的最重要的17位小数打印出结果。

  4. 因此,如果您在回合之前将值转换为Python float64对象,您将看到pleasanter输出(在某些情况下,结果可能会更准确一些)。但请注意,仅仅因为输出看起来不错,这并不意味着您获得的结果是准确的。这些都不会改变float 不能完全代表Python 0.58(或实际上使用相同格式的NumPy float)这一事实。请记住,使用二进制浮点,所见即所得。

    Python 3上的一些示例输出:

    float64

答案 1 :(得分:0)

似乎工作正常。请记住,round返回一个浮点数。

它四舍五入到两位小数,但浮点数本身就是精确的(对于几乎所有的数字),因此输出。