先日に行われたHaskell勉強会ではIOモナドの説明に入り、例題としてライフゲームが
ありました。http://gameage.blog58.fc2.com/blog-entry-1346.html
ライフゲームでは二次元のボードを用意し、1つのセルに対して周囲の八方向のセルを
チェックする必要があります。
ボードの角をチェックする場合でも、一貫性を持たせるためにボードは上下、左右が
つながっているようにすることで、周囲の八方向をチェック出来るようにしている。
そのボードの端をつなげる役割を果たす補助関数 wrap の中で剰余(Mod)を使用して
いたのですが、何故、それで出来るのか疑問に思ったわけです。
wrap :: Pos -> Pos
wrap (x,y) = (((x-1) `mod` width) + 1,(((y-1) `mod` height) + 1)
普段、私が使用しているVBやC#の言語仕様では、負数の場合 -1 mod 5 = -1 となるため
この式では成り立たないからです。
ところが、Haskellでは負数の場合 (-1) `mod` 5 = 4 となるため、反対側の位置を返す
ことが出来るわけです。
この負数の剰余について検索してみたところ、言語によって計算結果が違っています。
Modulo operation 言語ごとの一覧が書かれています。
http://en.wikipedia.org/wiki/Modulo_operation
■ C,VB,Java,JavaScript,VBA,Go (Dividend)
10 % 3 = 1
10 % -3 = 1
-10 % 3 = -1
-10 % -3 = -1
■ Perl,Ruby,Python,Lua,Haskell (Divisor)
10 % 3 = 1
10 % -3 = -2
-10 % 3 = 2
-10 % -3 = -1
※言語によっては両方に対応しているものもある。
負数の割り算が割りきれない
http://materia.jp/blog/20050803.html
剰余演算子の振る舞い
http://d.hatena.ne.jp/kazusato77/20080121/1200871085
負の数 余り 剰余系
http://oshiete.goo.ne.jp/qa/4051557.html