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

现象

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

/* 写法一 */
if (num % 2 == 0) {
    even();  // 偶数
} else {
    odd();  // 奇数
}
/* 写法二 */
if (num % 2 == 1) {
    odd();  // 奇数
} else {
    even();  // 偶数
}
/* 写法三 */
if (num % 2 != 0) {
    odd();  // 奇数
} else {
    even();  // 偶数
}
/* 写法四 */
if (num % 2 != 1) {
    even();  // 偶数
} else {
    odd();  // 奇数
}

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

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

分析

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

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

结论

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

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

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