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

时间:2011-05-04 23:46:33

标签: haskell

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

4 个答案:

答案 0 :(得分:160)

当第二个论点是否定时,它们不一样:

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

答案 1 :(得分:48)

是的,这些功能的行为不同。正如official documentation

中所定义

quot是截断为零的整数除法

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

答案 2 :(得分:10)

实际上说:

如果您知道两个操作数均为正数,则通常应使用quotremquotRem来提高效率。

如果你不知道两个操作数都是正数,你必须考虑你想要的结果。您可能不希望quotRem,但您可能也不想要divMod(x `div` y)*y + (x `mod` y) == x定律是一个非常好的定律,但是对负无穷大(Knuth风格除法)的舍入除了确保0 <= x `mod` y < y(欧几里德除法)之外通常没那么有用和效率低。

答案 3 :(得分:4)

如果您只想测试可分性,则应始终使用rem

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