2011-05-04 85 views
87

Haskell中的modrem之间的区别究竟是什么?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

不知道Haskell,但它可能是相同的操作。 'mod'ulus =='rem'ainder。 – 2011-05-04 23:49:05

+0

公平地说,这不是同一个问题。另一个问题假设理解这个问题的答案。 – 2011-05-05 03:40:33

+0

@丹读这个问题,因为我有另一个问题(http://stackoverflow.com/questions/5892188/problems-obtaining-the-list-of-divisors-of-a-number-in-haskell),我实现相同:/ – 2011-05-05 03:47:49

回答

123

他们是不一样的,当第二个参数为负:

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

的差异是相同的我在Clojure中对'rem'和'mod'有同样的问题,这就是答案。 – noahlz 2012-07-11 15:29:05

+9

当第一个参数为负时,它们也不一样。有关这些棘手操作的更多信息,请参阅http://stackoverflow.com/a/8111203/1535283和http://stackoverflow.com/a/339823/1535283。 – 2013-04-10 09:22:11

+4

也来自http:// stackoverflow。com/a/6964760/205521看起来'rem'是最快的。 – 2014-09-28 10:53:21

34

是,这些功能的行为不同。如在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 

 

+0

你最后的四个例子可能不是你的意思,因为'mod'和'rem'比'( - )'强。我编辑了您的评论,因为我似乎无法在此评论中添加多行内容。 – 2015-04-13 09:16:31

+1

@ErikHesselink:你在编辑时引入了一个错误。 '(-5)\'mod \'3 == 1' – 2016-04-19 16:37:46

+0

@ChengSun谢谢,我已经解决了。审查后应该生活。 – 2016-04-21 19:31:47

8

实事求是地讲:

如果您知道这两个操作数是肯定的,您通常应该使用quot,remquotRem来提高效率。

如果你不知道两个操作数都是肯定的,你必须考虑你想要结果的样子。你可能不想要quotRem,但你也可能不想要divMod(x `div` y)*y + (x `mod` y) == x法是一个非常好的法则,但是对负无穷(Knuth样式除法)的舍入除法确保0 <= x `mod` y < y(欧几里德除法)常常没那么有用也没有效率。

0

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

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