9

我正在尝试在hackerrank中解决这个问题。在某些时候,我必须检查一个数字是否除以 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)

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

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

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

4

1 回答 1

9

n // i和之间存在差异的主要原因n / in和是i类型intn % i == 0

  1. 的类型n // i仍然是int而类型n / ifloat并且
  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
>>> 
于 2017-10-07T17:39:05.847 回答