TL;DR:
在Java中,%符号在对负数取余的时候有可能得到负值,而Java里没有无符号整数类型,所以很容易不小心把负整数当作被除数,它会产生负值结果。
若需要类似Python中%的取模运算,得到最小正余数,应当使用Math.floorMod()(Java 8+)。
这是一个历史遗留问题
在K&R C中把%称为模除操作符(Modulus operator),但定义它的操作是取余数(Remainder)。而且当被除数为负数时的行为规定并不明确。后世由C发展而来的语言很多都被这个问题影响了。
取余数和取模的区别
余数的定义是(被除数-除数×商)。当被除数是负数,且不能整除时,会产生负的余数。
而取模在数论中通常使用的是最小正余数。
那么Math.floorMod()?
直接贴上标准库的Javadoc直观对比:
| 操作数a | 操作数b | Math.floorMod(a, b) | (a % b) |
| +4 | +3 | +1 | +1 |
| -4 | +3 | +2 | -1 |
| -4 | -3 | -1 | -1 |
| +4 | -3 | -2 | +1 |
这个方法早在Java 8就有了。
如果没有Java 8?
这都什么年代了(((
没关系,还有Guava能救——IntMath.mod()。
发表回复