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
答案 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)
实际上说:
如果您知道两个操作数均为正数,则通常应使用quot
,rem
或quotRem
来提高效率。
如果你不知道两个操作数都是正数,你必须考虑你想要的结果。您可能不希望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
,但rem
比mod
更快。