はじめに
Java の剰余演算、特に負の値が絡むときの挙動を 毎回のように忘れてしまう。自分のための備忘録としてこの記事を書きました。
% は被除数(左側)の符号を引き継ぐ
Java の % は「余り」ではありますが、結果の符号は被除数(左側の値)に従うという仕様になっています。そのため、負の数を左側に置くと結果も負になります。
System.out.println(-3 % 5); // => -3
System.out.println( 3 % -5); // => 3
System.out.println(-3 % -5); // => -3
数学的な mod(0 以上 n 未満の値)を期待していると、-3 % 5 が 2 になってほしいところですが、Java では -3 になります。
参考:Python の剰余は「除数の符号」に従う
Python の % は Java と異なり、結果の符号は除数(右側の値)に従うという仕様になっています。 そのため、常に「数学的な mod(0 以上 n 未満)」に近い挙動になります。
print(-3 % 5) # => 2
print(3 % -5) # => -2
print(-3 % -5) # => -3
常に正の剰余が欲しいときの解決策
1. Math.floorMod() を使う(推奨)
Java 8 以降では、数学的な意味での剰余を返す Math.floorMod() が利用できます。
System.out.println(Math.floorMod(-3, 5)); // => 2
負の値を扱う場面では、こちらを使う方が安全です。
2. 自前で正の剰余に変換する
% の結果を正の範囲に収めたい場合は、次のように調整する方法もあります。
int r = ((a % n) + n) % n;
動作環境
- Java 25
- Python 3.13.9