Puzzle 01: Oddity

Java中整数范围内的求余运算

下面先列一张表显示在不通的产品中对i % 3, i=-5..5的运算情况:

i%3

不同应用程序的运算结果有不同是因为余数定义本身造成的。余数的定义为:

对任意整数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

  1. JLS 15.17.2 Division Operator /
  2. JLS 15.17.3 Remainder Operator %
  3. Wikipedia: Remainder, 余数
  4. Java浮点数中的求余运算
  5. TODO 继续翻译维基词条。