2

我在下面的代码中将浮点数转换为整数。但是,结果输出对于镍币是不正确的。

代码:

actual = 25
paid = 26.65
cents = (paid-actual)*100
quarters = int(cents/25)
cents = cents %25
dimes = int(cents/10)
cents = cents %10
nickels = int(cents/5)
print quarters, dimes, nickels,cents
print 5.0/5,int(5.0/5)

输出:

6 1 0 5.0
1.0 1

预期产出

6 1 1 5.0
1.0 1

如果我明确地执行 int(5.0/5) 我得到 1 ,但是当将相同的操作分配给我的代码中的变量时,我得到 0 。我不确定为什么。有人可以解释吗?

4

4 回答 4

6

浮点数不能保证在您期望的数字上,它们可能只是勉强偏离,比如说5.0实际上可能是这样4.999...,并且由于int()截断/向下舍入,您会得到错误。

许多银行完全放弃了浮点问题,只使用 $1.00 = 100 我建议你也这样做,如下所示:

actual = 25
paid = 26.65
cents = int(round(paid*100)) #Turns 26.65 into 2665 before you do any float math
dollars = cents / 100
cents %= 100
quarters = cents / 25
cents %= 25
dimes = cents / 10
cents %= 10
nickels = cents / 5
print quarters, dimes, nickels,cents
print 5.0/5,int(5.0/5)

请注意,这会输出 2 1 1 5 因为那是 2 个季度、1 个硬币和 1 个镍 = $.65

通常,您希望尽可能晚地舍入以保持精度,但是当您使用金钱时,我认为完全使用整数会使浮点数的噩梦消失得更快。

此外,由于您使用的是 2.6,因此您需要转换为,int()因为round()直到 3.1 才返回整数

于 2013-07-24T03:45:21.180 回答
3

浮点数不能代表所有实数

每次你对浮点数做任何事情时,你都是在用你的浮点表示可以表示的最接近的东西来近似精确的结果。当你写

26.65

Python 实际使用

26.64999999999999857891452847979962825775146484375

当您使用浮点数进行数学运算时,结果将四舍五入到最接近的可表示数字。 print将浮点数截断到小数点后 12 位,因此小错误不可见,但是当您计算

int(cents/5)

cents实际上 is4.999999999999858cents/5is0.9999999999999716向下舍入为0.

于 2013-07-24T03:30:03.453 回答
2

其他用户已经解释了浮点数是如何不精确的。在您的情况下,请考虑使用Decimal更精确的计算:

>>> from decimal import Decimal
>>> actual = Decimal('25')
>>> paid = Decimal('26.65')
>>> actual,paid
(Decimal('25'), Decimal('26.65'))
>>> cents = (paid-actual)*100
>>> cents
Decimal('165.00')
>>> quarters = int(cents/25)
>>> cents = cents % 25
>>> dimes = int(cents/10)
>>> cents = cents %10
>>> nickels = int(cents/5)
>>> print quarters, dimes, nickels,cents
6 1 1 5.00
>>> cents
Decimal('5.00')

记下创建原始actual和的数字的字符串paid。他们是必需的。

于 2013-07-24T03:45:57.420 回答
1

当你这样做时int(x),它总是四舍五入,这意味着如果你这样做,int(4.9999)你会得到 4。考虑int(round(x))改用

编辑:

等等……如果你乘以 100,你为什么还要使用浮点数?你需要小数做什么?为什么不乘以 100 之后将 cents 转换为 int 然后摆脱所有这些浮点数的废话?

于 2013-07-24T03:22:06.433 回答