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


130

modremHaskell 之间的确切区别是什么?

两者似乎给出相同的结果

*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

3
不知道Haskell,但是很可能这些是相同的操作。modulus == rem气瓶。
马修·沙利

公平地说,这不是一个相同的问题。另一个问题假定理解了该问题的答案。
丹·伯顿

@Dan读了这个问题,由于我有另一个问题(stackoverflow.com/questions/5892188/…),我意识到了同样的问题:/
Oscar Mederos

2
divquot
newacct

Answers:


181

当第二个参数为负数时,它们是不同的:

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

20
我对同样的问题remmodClojure中,这是问题的答案。
noahlz 2012年

11
当第一个参数为负数时,它们也不相同。有关这些棘手操作的更多信息,请参见stackoverflow.com/a/8111203/1535283stackoverflow.com/a/339823/1535283
Scott Olson

4
同样从stackoverflow.com/a/6964760/205521看来,这rem是最快的。
Thomas Ahle 2014年

16
尽管这个答案是正确的,但对问题“有什么区别”仅要求“不相同”的答案是非常糟糕的。如果您可以扩展它们之间的“差异”以及某些用例,我将表示欢迎。
poitroae 2015年

59

是的,这些功能的行为有所不同。根据官方文档中的定义:

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

 


您的最后四个示例可能不是您的意思,因为mod和的rem关联比还要紧密(-)。由于我似乎无法在此评论中添加多行内容,因此我已编辑了您的评论。
Erik Hesselink

1
@ErikHesselink:您在编辑中引入了一个错误。(-5) `mod` 3 == 1
程新

@ChengSun谢谢,我已修复它。复审后应该是现场的。
Erik Hesselink

16

实际上来说:

如果你知道两个操作数是积极的,你应该经常使用quotremquotRem以提高效率。

如果您不知道两个操作数都是正数,则必须考虑要使结果看起来像什么。您可能不想要quotRem,但您可能也不想要divMod。该(x `div` y)*y + (x `mod` y) == x定律是一个很好的定律,但是向负无穷大四舍五入的划分(Knuth样式划分)通常比确保该定律0 <= x `mod` y < y(欧几里得划分)有用和效率低。


5

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

本质x `mod` y == 0上等同于x `rem` y == 0rem比更快mod

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.