ぎるばーとの日記

もっともっと遠くへ行きたい 空が広く見える場所まで

罠が潜んでいる!

 ワンライナーの陥穽。

 剰余(n rem m)演算とモジュロ(n mod m)演算はnが負のとき結果が違ってきます。端的に言うとモジュロ演算で結果が負の数になることはありません。(詳細は英語版ウィキペディアモジュロ演算。)
 例を挙げた方がいいか……。

n -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4
rem 3 -1 0 -2 -1 0 -2 -1 0 1 2 0 1
mod 3 2 0 1 2 0 1 2 0 1 2 0 1

 C言語Javaの%演算子は剰余演算なので、モジュロ演算の方は(必要なら)自分で書くことになります。

public static int mod(int n, int m) {
    if (m <= 0) {
        throw new ArithmeticException();
    }
    int rem = n % m;
    if (n < 0) {
        return rem + m;
    }
    else {
        return rem;
    }
}

 一部ではif文抜きでモジュロ演算する裏技(?)として、

(n % m + m) % m

が紹介されています。が、これは途中で足し算がオーバーフローすると悲惨なことになるので避けましょう。

    int m = Integer.MAX_VALUE;
    System.out.println(mod(10, m));
    System.out.println((10 % m + m) % m);
10
-2147483639

 一見よさそうに見えて罠が潜んでいる、という話でした。了。