python 除数总是提示为0_python负数求余不正确?——取模 VS 取余

前天小王同学正在leetcode兴致勃勃的刷题,用java写了一版后又习惯性的用python写了一版,代码逻辑完全一样,但提交答案后居然提示【解答错误】!

经过反复调试,发现问题出在涉及求余的地方,python和java得出的结果居然不一样?!

举个栗子

java的整除与求余

7/4 = 1
-7/4 = -1
7/-4 = -1
-7/-4 = 1
7%4 = 3
-7%4 = -3
7%-4 = 3
-7%-4 = -3

python3下的整除与求余

7//4 = 1
-7//4 = -2
7//-4 = -2
-7//-4 = 1
7%4 = 3
-7%4 = 1
7%-4 = -1
-7%-4 = -3

惊不惊喜,意不意外?

推理

我们用简单的数学语言来描述下:

对于整型数a,b来说,取模运算或者求余运算的方法都是:
求整数商: c = a/b;
计算模或者余数: r = a - c*b
但是求模运算和求余运算在第一步不同,取余运算在取c的值时,向0 方向舍入,而取模运算在计算c的值时,向负无穷方向舍入。

那么借助该知识点我们来再次推演下文章开头的例子

计算-7 Mod 4
那么:a = -7;b = 4;
第一步:求整数商c,c应该是-1.75,如进行求模运算c = -2(向负无穷方向舍入),求余运算则c = -1(向0方向舍入);
第二步:计算模和余数的公式相同,但因c的值不同,求模时r = 1,求余时r = -3。

结论

根据例子及推理。得出如下总结:

  1. 当a和b符号一致时,求模运算和求余运算所得的c的值一致,因此结果一致。

2. 当符号不一致时,结果不一样。求模运算结果的符号和b一致,求余运算结果的符号和a一致。

经过测试,在C/C++, C#, JAVA, PHP这几门主流语言中,%运算符都是做取余运算,而在python中的%是做取模运算。

扩展:维基百科的相关解释

维基百科-模除​zh.wikipedia.org 编程语言中,取余和取模的区别到底是什么?​www.zhihu.com

a0040fcd5544e306500a0c9843750529.png

a15ad41edd67a3e57ad34a4ccdac9e87.png

leetcode实例

整数反转 - 力扣(LeetCode)​leetcode-cn.com
a2029568b17ac0b8a083b57fc463e722.png

下面附上两个语言版本的代码实例,大家可以亲身体会下,当除数与被除数符号不一致时一定多多加小心:

Java版

class Solution {
    public int reverse(int x) {
        int rev = 0;
        while (x != 0) {
            int pop = x % 10;
            x /= 10;
            if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
            if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
            rev = rev * 10 + pop;
        }
        return rev;
    }
}

Python版

class Solution:
    def reverse(self, x: int) -> int:
        INT_MAX = pow(2,31) - 1
        INT_MIN = - pow(2,31)
        rev = 0
        while x!=0:
            if x > 0:
                pop = x%10
                x = x//10
            else:
                pop = x%-10
                x = -(x//-10)
            if rev > INT_MAX/10 or (rev== INT_MAX//10 and pop > 7):
                return 0
            if rev < INT_MIN/10 or (rev == INT_MIN//10 and pop < -8):
                return 0
            rev = rev*10 + pop            
        return rev
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值