Haskell中`mod`和`rem`的区别

Haskell中modrem的区别是什么?

两者似乎都给出了相同的结果

 *Main> mod 2 3 2 *Main> rem 2 3 2 *Main> mod 10 5 0 *Main> rem 10 5 0 *Main> mod 1 0 *** Exception: divide by zero *Main> rem 1 0 *** Exception: divide by zero *Main> mod 1 (-1) 0 *Main> rem 1 (-1) 0 

当第二个参数是负数时它们不一样:

 2 `mod` (-3) == -1 2 `rem` (-3) == 2 

是的,这些function的行为不同。 正如在官方文件中所定义的:

是整数除法截至零

rem是整数余数,满足:

 (x `quot` y)*y + (x `rem` y) == x 

div是整数除法向负无穷

mod是整数模量,满足:

 (x `div` y)*y + (x `mod` y) == x 

当使用负数作为第二个参数,结果不为零时,您可以真正注意到差异:

 5 `mod` 3 == 2 5 `rem` 3 == 2 5 `mod` (-3) == -1 5 `rem` (-3) == 2 (-5) `mod` 3 == 1 (-5) `rem` 3 == -2 (-5) `mod` (-3) == -2 (-5) `rem` (-3) == -2 

实际上讲:

如果你知道两个操作数是正的,你通常应该使用quotremquotRem来提高效率。

如果你不知道两个操作数都是肯定的,你必须考虑你想要的结果是什么样的。 你可能不需要quotRem ,但你可能不需要divMod(x `div` y)*y + (x `mod` y) == x定律是一个非常好的方法,但是对于负无穷(Knuth样式除法)的四舍五入往往不如确保0 <= x `mod` y < y (欧几里得除法)。

如果你只想testing可分性,你应该总是使用rem

本质上x `mod` y == 0相当于x `rem` y == 0 ,但remmod更快。