0

我正在使用 ceil() 函数将浮点计算的结果四舍五入到最接近的整数。经历了各种不同的输入...

int(ceil(A*B))

这里有一些例子来说明这个问题:

int(ceil(1.01*100)) = 101
int(ceil(1.02*100)) = 102
int(ceil(1.03*100)) = 103
int(ceil(1.04*100)) = 104
int(ceil(1.05*100)) = 105
int(ceil(1.06*100)) = 106
int(ceil(1.07*100)) = 107
int(ceil(1.08*100)) = 108
int(ceil(1.09*100)) = 110 ***
int(ceil(1.10*100)) = 111 ***
int(ceil(1.11*100)) = 112 ***
int(ceil(1.12*100)) = 113 ***
int(ceil(1.13*100)) = 113

我意识到这与正在执行的浮点计算有关......

1.09*100 = 109.000000.... > 109

我不知道如何可靠地捕获这个错误

尽管我有几种“粗略”的方法,例如下面概述的方法,但我认为这不是一个足够强大的解决方案

int(ceil((1.09*100)-0.00000001)) = 109
4

2 回答 2

3

您的问题既不是新问题也不是特定于 python 的,而是浮点计算所固有的。曾经使用过 Fortran 4 的所有恐龙都知道:作为程序员,必须知道计算的预期精度 ε。所以 :

  • 两个数 x 和 y 被认为是相等的,如果| x - y | < ε
  • 小于 x 的最大整数是floor(x + ε)
  • 大于 x 的最小整数是ceil(x - ε)

因此,您提出的解决方案是好的解决方案,前提是您有办法知道 ε 的良好值是多少。如果您正在编写一个模块,您应该允许用户指定它。

于 2014-04-30T16:08:51.010 回答
2

你是对的,问题源于浮点数的有限精度。

decimal模块是你的朋友:

from decimal import Decimal
from math import ceil

print int(ceil(Decimal("1.10") * 100))

请注意,您确实必须将数字作为字符串提供,否则它首先被 Python 解析为浮点数(在这里我们得到了我们想要避免的精度问题)。

于 2014-04-30T16:08:37.353 回答