Puzzle 01: Oddity
Java中整数范围内的求余运算
Java中整数范围内的求余运算
下面先列一张表显示在不通的产品中对i % 3, i=-5..5的运算情况:
不同应用程序的运算结果有不同是因为余数定义本身造成的。余数的定义为:
对任意整数a和任意非零整数b,满足:(a / b) * b + (a % b) == a;
并没有限定( a % b )一定为正还是负。
用Java写一个判断整数是否为余数的函数:
//错,无法正确判断负数的奇偶性
public static boolean isOdd(int i) {
return i % 2 == 1;
}
//正确,对正负整数都有效,易读,但效率不高。
public static boolean isOdd2(int i) {
return i % 2 != 0;
}
//正确,且高效率。一般情况下位运算比乘除运算的效率要高。
public static boolean isOdd3(int i) {
return (i & 1) != 0;
}
虽然最后一种写法比第二种写法效率高,但不宜过早优化,易读性还是很重要的。
求余运算的结果,在正整数范围内是有确定的结果的,但在整数范围内,一旦除数和被除数之一或全部为负时,结果就不确定了,不同的软件可能选择不同的实现方式。
具体关于余数方面的内容,参考维基条目Remainder。
附
- JLS 15.17.2 Division Operator /
- JLS 15.17.3 Remainder Operator %
- Wikipedia: Remainder, 余数
- Java浮点数中的求余运算
- TODO 继续翻译维基词条。