取模(%)行为对比
用同一组表达式 (10, 3)、(10, -3)、(-10, 3)、(-10, -3) 对比四种语言的 % 结果(见各语言源码)。
结果一览
| 表达式 | JavaScript | Go | Java | Python |
|---|---|---|---|---|
10 % 3 | 1 | 1 | 1 | 1 |
10 % -3 | 1 | 1 | 1 | -2 |
-10 % 3 | -1 | -1 | -1 | 2 |
-10 % -3 | -1 | -1 | -1 | -1 |
源码:js/mod-test.js · golang/mod_test.go · java/ModTest.java · python/mod_test.py
规律
JavaScript / Go / Java
余数符号与被除数(左操作数)相同;除法按零截断(truncated division)。
恒等式:a % b + (a / b) * b == a(其中 / 向零取整)。
Python
余数符号与除数(右操作数)相同;// 为向下取整(floor division)。
恒等式:a % b + (a // b) * b == a。
因此混用正负操作数时,Python 不仅符号规则不同,数值也可能与 C/Java/JS/Go 不同(如 10 % -3 为 -2 而非 1)。
何时结果相同
| 情况 | 四语言是否一致 |
|---|---|
两操作数同号且均为正(如 10 % 3) | 是 |
两操作数均为负(如 -10 % -3) | 是 |
一正一负(如 10 % -3、-10 % 3) | 否 |
示例
// JS:余数符号同左操作数
10 % 3; // 1
10 % -3; // 1
-10 % 3; // -1
-10 % -3; // -1
# Python:余数符号同右操作数;满足 a == (a//b)*b + (a%b)
10 % 3; # 1
10 % -3; # -2
-10 % 3; # 2
-10 % -3; # -1
// Go:与 JS / Java 相同
10 % 3; // 1
10 % -3; // 1
-10 % 3; // -1
-10 % -3; // -1
// Java:与 JS / Go 相同
10 % 3; // 1
10 % -3; // 1
-10 % 3; // -1
-10 % -3; // -1