Updated: 2019-01-01

入门

程序中取模运算通常写作%mod,比如 Java 中

jshell> System.out.println(1 % 2);
1

jshell> System.out.println(103 % 5);
3

Python 也一样

>>> 1 % 2
1
>>> 103 % 5
3

坑!

遇到负数,Java 和 Python 却返回了不同的结果:

jshell> System.out.println(-1 % 2);
-1

jshell> System.out.println(-103 % 5);
-3
>>> -1 % 2
1
>>> -103 % 5
2

进阶

区别在于结果的正负号和被除数相同还是和除数相同。Java 的%是和被除数相同的,而 Python 的%是和除数相同的。

解决方法是,如果 Java 里要和除数正负号相同,用Math.floorMod()

System.out.println(Math.floorMod(-1, 2));
# 1

System.out.println(Math.floorMod(-102, 5));
# 3

而 Python 要跟被除数符号相同,用math.fmod()

>>> import math
>>> math.fmod(-1, 2)
-1.0
>>> math.fmod(-103, 5)
-3.0

这个 wiki 页面列举了不同语言中的模运算的符号性。

Python 的这种特性,可以让我们通过x % 2 == 1来判断奇偶性,因为结果一定为 0 或 1。但 Java 里就不行了,结果可能是-1,所以通常用i % 2 != 0(i & 1) != 0来判断。