【问题标题】:Weird float to integer conversion issue in pythonpython中奇怪的浮点数到整数转换问题
【发布时间】: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,但还是会发生这种情况(我认为这个问题很普遍,但我使用这些数字遇到了它)。

【问题讨论】:

    标签: python numbers rounding number-formatting calculation


    【解决方案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)
      

      【讨论】:

        猜你喜欢
        • 2018-02-03
        • 1970-01-01
        • 2020-08-24
        • 2017-03-01
        • 2023-03-28
        • 2016-12-03
        • 2010-12-09
        • 1970-01-01
        • 2018-05-17
        相关资源
        最近更新 更多