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

Osc*_*ros 118 haskell

Haskell 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
Run Code Online (Sandbox Code Playgroud)

Fre*_*Foo 169

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

2 `mod` (-3)  ==  -1
2 `rem` (-3)  ==  2
Run Code Online (Sandbox Code Playgroud)

  • 我在Clojure中有关于`rem`和`mod`的相同问题,这就是答案. (20认同)
  • 虽然这个答案是正确的,但对于"有什么不同"的问题,一个声称只是"不一样"的答案是非常糟糕的.如果你可以扩展它们的"如何"以及可能的某些用途,我会欢迎它. (12认同)
  • 当第一个论点是否定时,它们也不相同.有关这些棘手操作的更多信息,请参见http://stackoverflow.com/a/8111203/1535283和http://stackoverflow.com/a/339823/1535283. (10认同)
  • 同样来自http://stackoverflow.com/a/6964760/205521似乎`rem`是最快的. (4认同)

Giu*_*one 51

是的,这些功能的行为不同.如官方文档中所定义:

quot 是整数除法被截断为零

rem 是整数余数,满足:

(x `quot` y)*y + (x `rem` y) == x
Run Code Online (Sandbox Code Playgroud)

div 是整数除法截断为负无穷大

mod 是整数模数,满足:

(x `div` y)*y + (x `mod` y) == x
Run Code Online (Sandbox Code Playgroud)

当您使用负数作为第二个参数且结果不为零时,您可以真正注意到差异:

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
Run Code Online (Sandbox Code Playgroud)

 


dfe*_*uer 10

实际上:

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

如果你不知道两个操作数都是正数,你必须考虑你想要的结果.你可能不想要quotRem,但你可能也不想要divMod.该(x `div` y)*y + (x `mod` y) == x法是一个非常好的一个,但舍师向负无穷大(高德纳风格划分)常常是那么有用,比保证效率较低0 <= x `mod` y < y(欧几里得师).


sja*_*obi 8

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

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

  • 至少在“Int”和“Integer”的情况下,“mod”是根据“rem”实现的,但需要一些额外的检查:http://hackage.haskell.org/package/ghc-prim-0.7。 0/docs/src/GHC-Classes.html#modInt%23,http://hackage.haskell.org/package/integer-gmp-1.0.3.0/docs/src/GHC.Integer.Type.html#modInteger (2认同)