简体   繁体   English

x%(1e9 + 7) 和 x%(10**9 + 7) 在 Python 中是否不同? 如果是,为什么?

[英]Is x%(1e9 + 7) and x%(10**9 + 7) different in Python? If yes, why?

For an integer x, x % (10 ** 9 + 7) and x % (1e9 + 7) are giving different results after a few iterations.对于 integer x, x % (10 ** 9 + 7)x % (1e9 + 7)在几次迭代后给出不同的结果。 To reproduce this results, I am sharing my solution for LeetCode #576.为了重现这个结果,我将分享我的LeetCode #576 解决方案。 Out of Boundary Paths .越界路径 My solution won't pass 5 out 94 test cases if I change return ans % (10 ** 9 + 7) to return ans % (1e9 + 7) (realising this took me an hour).如果我将return ans % (10 ** 9 + 7)更改为return ans % (1e9 + 7) (意识到这花了我一个小时),我的解决方案不会通过 94 个测试用例中的 5 个。

Note that this solution is much longer than one-liner presented by some genius guy here .请注意,这个解决方案比这里的一些天才提出的单线要长得多。 However, the same problem arises with his solution if we change % (10 ** 9 + 7) to % (1e9 + 7) .但是,如果我们将% (10 ** 9 + 7)更改为% (1e9 + 7) ,他的解决方案也会出现同样的问题。

I played a bit with the python compiler and noticed that 1e9 gives a float literal.我用 python 编译器玩了一下,注意到 1e9 给出了一个浮点文字。 So it seems to me that this peculiarity is caused by 'weirdness' of floating point arithmetic.所以在我看来,这种特殊性是由浮点运算的“怪异”引起的。 But I still don't understand how a zero after decimal point can cause difference.但我仍然不明白小数点后的零如何导致差异。 Why is this difference arising?为什么会出现这种差异?

Without reproducing, differences can be found here: https://www.diffchecker.com/PyKQCElB无需复制,可以在这里找到差异: https://www.diffchecker.com/PyKQCElB

To reproduce, here's my solution:要重现,这是我的解决方案:


class Solution:
    def findPaths(self, m: int, n: int, maxMove: int, startRow: int, startColumn: int) -> int:
        if maxMove == 0:
            return 0
        current_state = [[0 for _ in range(n)] for _ in range(m)]
        next_state = [[0 for _ in range(n)] for _ in range(m)]
        current_state[startRow][startColumn] = 1
        ans = self.count_ways(m, n, current_state)
        
        k = 1
        while k < maxMove:
            # print("CS:", current_state)
            for i in range(m):
                for j in range(n):
                    next_state[i][j] = 0
                    if i != 0:
                        next_state[i][j] += current_state[i-1][j]
                    if i!= m-1:
                         next_state[i][j] += current_state[i+1][j]
                    if j != 0:
                        next_state[i][j] += current_state[i][j-1]
                    if j != n-1:
                        next_state[i][j] += current_state[i][j+1]
            
            current_state, next_state = next_state, current_state
            ans += self.count_ways(m, n, current_state)
            
            # print("NS:", current_state)
            # print("k:{},ans:{}".format(k, int(ans % 10 ** 9 + 7)))            
            # print("k:{},ans:{}".format(k, int(ans % 1e9 + 7)))            

            k += 1
            
        # return ans % (1e9 + 7)  # This is giving incorrect results.
        return ans % (10 ** 9 + 7)  # This works fine.
        
    def count_ways(self, m, n, grid):
        ways = 0
        for i in range(m):
            for j in [0, n-1]: # Checking left and right strips of a grid.
                ways += grid[i][j]
                 
        for j in range(n):
            for i in [0, m-1]: # Checking top and bottom strips of a grid.
                ways += grid[i][j]
                
        # This will automatically add corner boxes twice.
        
        return ways

EDIT: Use this test case (arguments to findPaths , in order):编辑:使用这个测试用例(参数findPaths ,按顺序):

36
5
50
15
3

But I still don't understand how a zero after decimal point can cause difference.但我仍然不明白小数点后的零如何导致差异。

Where the decimal point isn't important.小数点不重要的地方。 It's floating!它在漂浮!

Why is this difference arising?为什么会出现这种差异?

Because floating point numbers in Python are the usual hardware ones which means they have limited storage and precision:因为 Python 中的浮点数是常用的硬件数,这意味着它们的存储和精度有限:

>>> int(123123123123123123123.0)
123123123123123126272
#                ^^^^ different!

But integer numbers in Python have infinite storage and precision ("bignum"):但是 Python 中的 integer 数字具有无限的存储空间和精度(“bignum”):

>>> int(123123123123123123123)
123123123123123123123

So:所以:

>>> 123123123123123123123 % 10**9
123123123

>>> 123123123123123123123 % 1e9
123126272.0

In the second case both sides are converted to floating point because one of them is.在第二种情况下,双方都转换为浮点数,因为其中之一是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM