如何处理python math.ceil中的舍入错误

时间:2015-07-15 13:41:41

标签: python math

以下代码片段结果为6:

import math
number = (1 - 0.99) * 500
math.ceil(number)

虽然(数学上)正确的答案是5.可能这是一个舍入问题 - 执行正确解决方案的最佳方法是什么?

4 个答案:

答案 0 :(得分:3)

  

据推测这是一个舍入问题

是:

>>> 1 - 0.99
0.010000000000000009
>>> (1 - 0.99) * 500
5.000000000000004
  

执行正确解决方案的最佳方法是什么?

您可以使用decimal.Decimal代替float

>>> from decimal import Decimal
>>> import math
>>> (1 - Decimal("0.99")) * 500
Decimal('5.00')
>>> math.ceil((1 - Decimal("0.99")) * 500)
5.0

答案 1 :(得分:2)

这是一个浮点错误,因为有些数字无法准确表示(无限多个数字必须使用有限数量的位来表示 - 必须进行一些权衡)。这就是浮点运算失去一些精度的原因:

>>> 1-0.99
0.010000000000000009

尝试十进制:

>>> from decimal import Decimal as d
>>> result = (1 - d("0.99")) * 500
>>> result
Decimal('5.00')
>>> math.ceil(result)
5.0

修改

看起来所有数字都有精确的表示形式:

>>> a = 1.0; b = 0.99; c = 0.01
>>> a, b, c
(1.0, 0.99, 0.01)

所以这个结果可能看起来很令人惊讶:

>>> a - b
0.010000000000000009
>>> a - b == c
False

但这只是累积的精度和舍入误差。以下是相同的数字和计算,但显示更多数字:

>>> def o(f): return "%.30f" % f
>>> o(a)
'1.000000000000000000000000000000'
>>> o(b)
'0.989999999999999991118215802999'
>>> o(c)
'0.010000000000000000208166817117'
>>> o(a-b)
'0.010000000000000008881784197001'

答案 2 :(得分:0)

Python 2.7舍入到17位有效数字。它是真实数学的不同模型

答案 3 :(得分:0)

给定的答案是正确的,这是舍入错误的情况。但是,我认为包括为什么会发生这种情况会很有用。

在硬件中,浮点数是基数2(AKA二进制)。问题是大多数小数部分不能完全表示为binary fractions。它的转换(通常)浮点数仅由实际存储在机器中的二进制浮点数近似。