python中奇怪的浮点数到整数转换问题
Posted
技术标签:
【中文标题】python中奇怪的浮点数到整数转换问题【英文标题】:Weird float to integer conversion issue in python 【发布时间】:2021-01-03 15:22:03 【问题描述】:对于我编写的涉及有限代数域的程序计算,我需要检查(2**58-1)/61
是否为整数。然而python似乎表明它是,虽然它是not。
例如-
>>> (2**58-1)/61
4725088133634619.0
即使在使用 numpy
函数时也会出现此问题 -
>>> np.divide(np.float64(2**58)-1,np.float64(61))
4725088133634619.0
虽然 python 确实正确计算了 2**58
,但还是会发生这种情况(我认为这个问题很普遍,但我使用这些数字遇到了它)。
【问题讨论】:
【参考方案1】:如果您使用普通的/
除法,您的结果是一个浮点数,具有相关的有限精度。结果被四舍五入,在你的情况下,它被四舍五入为 4725088133634619.0 - 但这并不能证明它是一个整数。
如果要检查除以61的结果是否为整数,请使用模运算符测试除以61的余数是否为0:
>>> (2**58-1) % 61
45
如您所见,事实并非如此。
【讨论】:
谢谢!但是怎么用np.float64
的时候还是四舍五入呢?
@proton:这个数字正好适合浮点精度下降到个位数。 .0
是多余的,只是为了表明它的类型是 float
。【参考方案2】:
至于@Thierry Lathuille 提到的浮点有限精度,Python 的float
使用64
位并且是双精度,为尾数提供53
位(np.float64
也是如此)。这意味着并非所有数字> 2**53
都可以使用float
表示,我们会损失精度。例如,2**53
== 2**53 + 1
在双精度下为真。更详细的在这里:
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
Is floating point math broken?
【讨论】:
【参考方案3】:已经给出了正确的答案。我只是添加另一种方法(与已经说过的没有太大区别)。
由于表示错误的固有限制,您可能想要做的是对 python 使用 divmod(),对 numpy 使用 numpy.divmod()。这样您就可以检查商和余数。
print(divmod((2**58-1),61))
给出商和余数
(4725088133634618, 45)
在 numpy 中,您可能希望使用类似的 divmod 函数,但数字应该是 np.int 类型而不是 np.float 类型(由于上述表示错误)。
np.divmod(np.int64(2**58)-1,np.int8(61))
上面给出了商和余数。
(4725088133634618, 45)
【讨论】:
以上是关于python中奇怪的浮点数到整数转换问题的主要内容,如果未能解决你的问题,请参考以下文章