%

剰余演算(割ったあまりを求める。%とかmodという演算子が使われることが多い)における、割ったあまりという定義は自明なようだけど、負の数を割ったあまりとなるとちょっとややこしい。

CやJavaですと、

-12 % 7

は-5になります。

一方perlやrubyでは

-12 % 7

は2になります。どちらも数学的には同じ剰余類になる数なので、挙動としては問題ないと思いますが、個人的には剰余の結果は0~6であって欲しいなと思います。(つまりperlやrubyのほう)

やはり代表元が0~6固定のほうが気持ちいい。

結局のところaをbで割ったあまりというのは

a = q * b + r

で 0 <= b < r となってるのが自然だと思うんですよね。負の時だけ rの範囲が変わるのはあまり気持ちよくありませんし、実際使用する場合も条件文を入れないといけないから扱いにくいかなぁと。

## % 7 (C)# % 7 (perl)
922
811
700
666
555
444
333
222
111
000
-1-16
-2-25
-3-34
-4-43


何故ならもしC言語での仕様だとすると7で割った余りは大きい数からカウントダウンしていくと、6,5,4,3,2,1,0,6,5,4,.. の繰り返しで続いてくるのに、0のところで不連続となってしまいます。ここは6,5,4,3,... とカウントダウンしていってくれたほうが便利です。

ちなみに割った余りというのは整数(特に正の数の場合)だから自明なわけで、ガウス整数とか二次体の整数とか考えると、rの範囲とかがすごく複雑になっちゃいますね。 負の数に拡張する比じゃない?

コメント一覧

bc に聞いてみよう % bc bc 1.06 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 12%7 5 -12%7 -5 おお、Cパターンだ。 python は 0<=b<r パターンでした。 ガウス整数ってなんだっけ・・・複素数のやつ?タイルとかのパターンみたいなのを見たことがあるかも
jack

その後さらに確認したところ、awkもCパターンでした。 ガウス整数は a+biみたいな形をした整数ですね。
Isami

今更ですが、wikiで定義見ると、剰余rは 0<=r<b と成ってますね。昔、8bit時代に気になってマシン語レベルで調べたような…。
kaz

あっ、HTMLタグとして処理されてしまったみたい。 0<=r<b です。
kaz

うああ、何だかボールドに成りっぱなしみたい。 重ね重ねすまんこってす。</b> テストテストvvv
kaz

<b>の問題は修正しますたw 確かに、剰余は 0<=r<bとなっているのが計算機で処理するには都合がいいですね。商と余りが一意に決まり、かつ、余りが割る数より小さいと。 ただ、今回これが整数だからいいけれど、ガウス整数とか二次体の整数とかになると、余りを割る数より小さくするにはどうすればいいのかとか、整除の一意性とかが非常にやっかいになってきます。 たとえばガウス整数ではノルムで評価をするけれど、それと同じように、整数の場合も剰余を絶対値で評価をするすると、たとえば、7で割ったあまりなら6でもいいし、-1でもよくなってしまう。 ただしこの場合は整除の一意性が成り立たなくなってしまいます。一意性をもたせるには範囲が7に収まっていなければならないと。 一方環論的な立場に立つと、代表元が重要なので、-1と書いても6と書いても表現上の記号の違いでしかないわけで、そういう意味ではCの剰余も間違っていないかなと思うわけです。
Isami