導入
Javaでプログラミングをしているとき、剰余演算子(%)を使って「配列のインデックスを循環させる」といった処理を書くことはよくあります。しかし、負の数を扱う際に「期待した結果と違う!」と戸惑ったことはありませんか?Javaの%演算子は「剰余」ではなく「余り」を計算するため、負の数が絡むと直感に反する挙動をします。この課題をスマートに解決するのが、Java 8から導入されたMath.floorMod()メソッドです。
基礎知識
まず、Javaの「%」演算子について理解しましょう。Javaの%演算子は、被除数(割られる数)の符号を結果に反映させる性質があります。
例えば、-5 % 3 を実行すると、結果は -2 になります。数学的な「剰余(mod)」の考え方では、結果は常に正(この場合は1)になるべきですが、Javaの仕様上は負の値が返ってきてしまうのです。
一方、Math.floorMod(x, y)は、算術的な「床関数(floor)」に基づいた剰余を計算します。これにより、負の数が含まれていても、常に除数(割る数)と同じ符号を持つ(または0)の、数学的に正しい剰余を求めることができます。
実装/解決策
Math.floorMod()を使用することで、負の数の剰余計算が必要なアルゴリズム(循環バッファやハッシュ関数のインデックス計算など)において、条件分岐(if文で負か判定して補正するなど)を書く必要がなくなります。コードが簡潔になり、バグの混入を防ぐことができます。
サンプルプログラム
以下のコードを実行して、%演算子とMath.floorMod()の違いを確認してみてください。
public class ModuloExample {
public static void main(String[] args) {
int x = -5;
int y = 3;
// 従来の % 演算子での計算
// 結果は -2 になります
int remainder = x % y;
System.out.println(“x % y の結果: ” + remainder);
// Math.floorMod() を使用した計算
// 結果は 1 になります(数学的な剰余)
int floorMod = Math.floorMod(x, y);
System.out.println(“Math.floorMod(x, y) の結果: ” + floorMod);
// 応用例:配列のインデックスを逆方向に循環させる
String[] items = {“A”, “B”, “C”};
int currentIndex = 0;
int nextIndex = Math.floorMod(currentIndex – 1, items.length);
System.out.println(“逆方向に移動したインデックス: ” + nextIndex); // 2 が表示されます
}
}
応用・注意点
現場での開発において、Math.floorMod()を使う際に注意すべき点が2つあります。
1つ目は、除数が0の場合です。これはMath.floorMod()でも%演算子と同様に「ArithmeticException」が発生します。ゼロ除算の可能性が少しでもある場合は、事前にチェックを行うか、try-catchで適切にハンドルしてください。
2つ目は、可読性の観点です。チームメンバーがMath.floorMod()を知らない場合、コードレビューで「なぜこれを使っているの?」と聞かれることがあります。そうした場合は、本記事のように「負の数が発生した時の数学的な整合性を保つため」と説明できるようにしておきましょう。
算術演算子や比較演算子を多用するロジックでは、こうした標準ライブラリの挙動を正しく理解しておくことが、バグのない堅牢なコードを書く第一歩となります。ぜひ、次回の開発から意識的に活用してみてください。

コメント