来自haskell报告:
如果y不为零,则quot,rem,div和mod类方法满足这些定律:
(x `quot` y)*y + (x `rem` y) == x (x `div` y)*y + (x `mod` y) == x
quot
是整数除法被截断为零,而结果div
被截断为负无穷大.
例如:
Prelude> (-12) `quot` 5 -2 Prelude> (-12) `div` 5 -3
结果如何截断的区别在哪里?
许多语言都有一个"mod"或"%"运算符,它在除法后给出余数,截断为0; 例如C,C++和Java,可能还有C#,会说:
(-11)/5 = -2 (-11)%5 = -1 5*((-11)/5) + (-11)%5 = 5*(-2) + (-1) = -11.
Haskell的quot
和rem
旨在模仿这种行为.我可以想象在一些人为的情况下,可能需要与某些C程序的输出兼容.
Haskell的div
和mod
,随后Python的/和%,跟随数学家(至少数理论家)的约定,始终截断下来师(不计入0 -接近负无穷大),这样的形式始终是负数.因此在Python中,
(-11)/5 = -3 (-11)%5 = 4 5*((-11)/5) + (-11)%5 = 5*(-3) + 4 = -11.
Haskell div
并mod
遵循这种行为.
实际上,虽然C99和C++ 11确实指定了截断到0的定义,但是早期的版本使其保留了实现定义,因此"与C的兼容性"是其他语言或程序不太可能(或至少是坏...)的原因.截断到0.
2> luqui..:这不完全是你问题的答案,但在x86上的GHC中,Int上的quotRem将编译为单个机器指令,而divMod则做了相当多的工作.因此,如果您处于速度关键部分并且只处理正数,那么可以使用quotRem.
为了解决SPOJ素数,使用rem而不是mod使我的测试文件运行在4.758s而不是5.533s.这意味着在32位Ubuntu,Haskell Platform 2011下,更快版本的速度提高了16%.
3> namin..:一个简单的例子就是测试整数是偶数还是奇数.
let buggyOdd x = x `rem` 2 == 1 buggyOdd 1 // True buggyOdd (-1) // False (wrong!) let odd x = x `mod` 2 == 1 odd 1 // True odd (-1) // True当然,请注意,您可以通过以这种方式定义odd来避免考虑这些问题:
let odd x = x `rem` 2 /= 0 odd 1 // True odd (-1) // True一般来说,只要记住,因为
y > 0
,x mod y
总是返回一些东西,>= 0
同时x rem y
返回0或与x相同的符号.