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

如何处理python math.ceil中的舍入错误,python,math,Python,Math,以下代码段给出了6个结果: import math number = (1 - 0.99) * 500 math.ceil(number) 而(数学上)正确的答案是5。这大概是一个舍入问题——实施正确解决方案的最佳方式是什么 这大概是一个舍入问题 是的: 实施正确解决方案的最佳方式是什么 您可以使用浮点数代替浮点数: >>> from decimal import Decimal >>> import math >>> (1 - Decim

以下代码段给出了6个结果:

import math
number = (1 - 0.99) * 500
math.ceil(number)
而(数学上)正确的答案是5。这大概是一个舍入问题——实施正确解决方案的最佳方式是什么

这大概是一个舍入问题

是的:

实施正确解决方案的最佳方式是什么

您可以使用浮点数代替
浮点数

>>> from decimal import Decimal
>>> import math
>>> (1 - Decimal("0.99")) * 500
Decimal('5.00')
>>> math.ceil((1 - Decimal("0.99")) * 500)
5.0
这大概是一个舍入问题

是的:

实施正确解决方案的最佳方式是什么

您可以使用浮点数代替
浮点数

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

这是一个浮点错误,因为有些数字不能精确地表示(无限多的数字必须用有限的位数表示——必须有一些折衷)。这就是为什么浮点运算会丢失一些精度:

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

这是一个浮点错误,因为有些数字不能精确地表示(无限多的数字必须用有限的位数表示——必须有一些折衷)。这就是为什么浮点运算会丢失一些精度:

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

Python 2.7四舍五入到17位有效数字。这是一个与真实数学不同的模型

Python 2.7轮到17位有效数字。这是一个与真实数学不同的模型

给出的答案是正确的,这是一种舍入错误。然而,我认为将这种情况发生的原因包括在内是有益的


在硬件中,浮点数是以2为基数的(也称为二进制)。问题是大多数小数不能精确地表示为。(通常)浮点数的翻译仅由机器中实际存储的二进制浮点数近似。给定的答案是正确的,这是舍入错误的情况。然而,我认为将这种情况发生的原因包括在内是有益的


在硬件中,浮点数是以2为基数的(也称为二进制)。问题是大多数小数不能精确地表示为。一般来说,浮点数的转换只能用机器中实际存储的二进制浮点数来近似。

您能使用
decimal.decimal
类吗?您的问题的简短/一般回答是,您无法使用浮点数“强制执行正确的解决方案”。为了给您建设性的答案,我们应该知道在这个结果中有什么困扰您。更准确地说,对于什么样的应用案例,这会产生影响?正如您所知,0.9900000应产生5,但非常接近的0.9899999应产生6,因此您处于临界状态。您是否能够使用
decimal.decimal
类?您的问题的简短/一般回答是,您无法使用浮点数“强制执行正确的解决方案”。为了给您建设性的答案,我们应该知道在这个结果中有什么困扰您。更准确地说,对于什么样的应用案例,这会产生影响?正如你所知,0.9900000应该产生5,但是非常接近的0.989999应该产生6,所以你处于一个临界点上。误导性的例子是,转换为
int
将始终截断,并使这看起来即使对于纯
浮点
s也有效。哎呀,从我的交互式会话复制了错误的行。谢谢。有误导性的例子,对
int
的转换将始终截断,并使其看起来即使对普通
float
s也有效。Oops,从我的交互式会话中复制了错误的行。谢谢,“Python2.7循环到17位有效数字”-这也不完全正确,这只是它的显示方式。简短的版本是,不可能在有限的二进制位中表示所有无限多的实数,这是所有浮点实现的共同问题,而不仅仅是Python的问题。“Python 2.7舍入到17位有效数字”-这也不完全正确,只是它的显示方式。简短的版本是,不可能在有限的二进制位中表示所有无限多的实数,这是所有浮点实现都会遇到的问题,而不仅仅是Python。