【问题标题】:Weird behaviour of division in pythonpython中除法的奇怪行为
【发布时间】:2018-03-14 16:47:45
【问题描述】:

我正在尝试解决hackerrank 中的this 问题。在某些时候,我必须检查一个数字是否除以 n(给定输入)。

此代码运行良好,除了一个测试用例(不是问题):

if __name__ == '__main__':
    tc = int(input().strip())
    for i_tc in range(tc):
        n = int(input().strip())
        while n % 2 == 0 and n is not 0:
            n >>= 1
        last = 0



        for i in range(3, int(n ** 0.5), 2):
            while n % i == 0 and n > 0:
                last = n
                n = n // i        # Concentrate here


        print(n if n > 2 else last)

现在您可以看到,我仅在 i 是 n 的因数时才在除数。例如,如果数字是 i = 2 和 n = 4,则 n / 2 和 n // 2 不等于区别吧。

但是当我使用下面的代码时,所有的测试用例都失败了:

if __name__ == '__main__':
    tc = int(input().strip())
    for i_tc in range(tc):
        n = int(input().strip())
        while n % 2 == 0 and n is not 0:
            n >>= 1
        last = 0
        for i in range(3, int(n ** 0.5), 2):
            while n % i == 0 and n > 0:
                last = n
                n = n / i      # Notice this is not //
        print(n if n > 2 else last)

这不是第一次了。即使是this 问题我也遇到了同样的问题。对于这个问题我只需要除以 2,所以我使用右移运算符来摆脱这个问题。但在这里我不能做任何事情,因为右移帮不了我。

为什么会这样?如果数字很小,我看不出任何区别,但随着数字变大,它的行为会有所不同。

当 / 失败时使用 // 甚至都不直观。这是什么原因?

【问题讨论】:

  • 你的 Python 版本是多少?
  • 在 python 3 n / 2 和 n // 2 中是不同的。 4/2 ==2.0 和 4//2 == 2
  • @JamesKPolk:对于这个特殊问题,(2) 不是问题,因为所有整数都在可表示的范围内(从问题描述来看,最大值 n10**12) ,并且所有浮点除法和模运算都应该给出准确的结果。但我完全同意第 (3) 点。
  • 我不明白你的第一个代码是如何工作的。我相信当n 是一个奇数平方数时它会失败。 (range 不包括第二个端点)
  • @JamesKPolk:我怀疑失败只是与打印出带有尾随.0 的整数浮点数有关。因此,对于51 的输入(例如),该站点期望字符串"17" 作为输出,但会得到"17.0"

标签: python math primes floor floor-division


【解决方案1】:

考虑到niintn % i == 0 类型,n // in / i 之间存在差异的主要原因是

  1. n // i 的类型仍然是int,而n / i 的类型是float
  2. Python 中的整数具有无限精度,而浮点数的精度是有限的。

因此,如果n // i 的值超出了python float 类型可以准确表示的范围,那么它将不等于n / i 的计算值。

插图:

>>> (10**16-2)/2 == (10**16-2)//2
True
>>> (10**17-2)/2 == (10**17-2)//2
False
>>> int((10**17-2)//2)
49999999999999999
>>> int((10**17-2)/2)
50000000000000000
>>> 

【讨论】:

  • '任意'而不是'无限'
  • 谢谢你...你已经清楚地了解了正在发生的事情!
猜你喜欢
  • 1970-01-01
  • 2019-12-03
  • 2020-10-22
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多