Haskell中`mod`和`rem`的区别
Haskell中mod
和rem
的区别是什么?
两者似乎都给出了相同的结果
*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
实际上讲:
如果你知道两个操作数是正的,你通常应该使用quot
, rem
或quotRem
来提高效率。
如果你不知道两个操作数都是肯定的,你必须考虑你想要的结果是什么样的。 你可能不需要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
,但rem
比mod
更快。