どう書く?org のこのお題,はじめはHaskellで書いた。
modular n l h = l + n `mod` (h - l + 1)
すでに投稿があったのでOCamlで書き直したんだけど,そのまま移植したんではうまくいかない。
# let modular n l h = l + n mod (h - l + 1);; val modular : int -> int -> int -> int = <fun> # modular (-1) 100 200;; - : int = 99
しばらく悩んだけど,要するに mod の引数に負数が現れた場合の振る舞いが Haskell と OCaml で違う。思わぬ盲点だよな。
Haskellの場合:
Prelude> mod (-1) 10 9 Prelude> mod 1 (-10) -9
OCamlの場合:
# (-1) mod 10;; - : int = -1 # 1 mod (-10);; - : int = 1
さて,算術的にはどっちが正しいんだろうか。
Haskell には divMod と quotRem があります。
割った余りというと rem (remainder) のことで、
mod は合同式の言葉です。
http://ja.wikipedia.org/wiki/%E5%90%88%E5%90%8C%E5%BC%8F
なので -1 `mod` 10 == 9 `mod` 10 となるべきです。
OCaml の mod は Haskell の rem のようですが、
ちょっと不適切なのではないでしょうか。