使用模运算进行奇偶判断的正确写法

本文发布于 0.3 年前,最近编辑于 111 天前,请注意识别信息的时效性。

本文地址:https://www.jeddd.com/article/correct-way-of-using-modulo-to-test-parity.html

通过取模运算来判断整数的奇偶性在编程中非常常见,但其中有一个小小的细节容易被忽视。

现象

考虑以下四种不同的写法(以 C/C++/Java 为例),并注意 if 判断条件的不同:

/* 写法一 */
if (num % 2 == 0) {
    doEvenOperation();  // 判断为偶数
} else {
    doOddOperation();  // 判断为奇数
}
/* 写法二 */
if (num % 2 == 1) {
    doOddOperation();  // 判断为奇数
} else {
    doEvenOperation();  // 判断为偶数
}
/* 写法三 */
if (num % 2 != 0) {
    doOddOperation();  // 判断为奇数
} else {
    doEvenOperation();  // 判断为偶数
}
/* 写法四 */
if (num % 2 != 1) {
    doEvenOperation();  // 判断为偶数
} else {
      doOddOperation();  // 判断为奇数
}

根据 if 条件中的符号为等号(==)或不等号(!=),以及数字是 0 或 1,由排列组合可以得到上面四种写法。

对于正整数(正奇数和正偶数)来说,显然四种写法都能够得到正确结果。然而,容易忽视的是负数的情况——若参数 num负奇数,则有些写法其实是错误的。如当 num = -3 时,写法一、二、三、四得出的结果分别为奇、偶、奇、偶,也就是说写法二和写法四是错误的。

分析

造成错误的原因不难理解:在 C/C++/Java 等语言中,整数取模的符号与被除数相同,因此在 if 判断的时候如果将余数与 1 进行比较就会出问题,因为负奇数模 2 的余数是 -1。而偶数不会有这个问题,因为正偶数和负偶数模 2 的结果都是 0。

另外这里需要说明一点:Python 与其他多数语言的取模运算(%)的行为不同。Python 中余数的符号与除数(而不是被除数)相同,因此在 Python 中,上面四种写法得出的结果都是正确的。

结论

无论使用什么编程语言,如果要使用模运算来进行奇偶性判断,个人建议统一使用第一种写法,即:

/* 写法一 */
if (num % 2 == 0) {
    doEvenOperation();  // 判断为偶数
} else {
    doOddOperation();  // 判断为奇数
}

注:本文仅讨论模运算。判断奇偶还有其他方法,本文暂不详述。

本文地址:https://www.jeddd.com/article/correct-way-of-using-modulo-to-test-parity.html

添加新评论

评论列表