When is the difference between quotRem and divMod useful?

孤街醉人 提交于 2019-11-27 11:19:29
ShreevatsaR

Many languages have a "mod" or "%" operator that gives the remainder after division with truncation towards 0; for example C, C++, and Java, and probably C#, would say:

(-11)/5 = -2
(-11)%5 = -1
5*((-11)/5) + (-11)%5 = 5*(-2) + (-1) = -11.

Haskell's quot and rem are intended to imitate this behaviour. I can imagine compatibility with the output of some C program might be desirable in some contrived situation.

Haskell's div and mod, and subsequently Python's / and %, follow the convention of mathematicians (at least number-theorists) in always truncating down division (not towards 0 -- towards negative infinity) so that the remainder is always nonnegative. Thus in Python,

(-11)/5 = -3
(-11)%5 = 4
5*((-11)/5) + (-11)%5 = 5*(-3) + 4 = -11.

Haskell's div and mod follow this behaviour.

This is not exactly an answer to your question, but in GHC on x86, quotRem on Int will compile down to a single machine instruction, whereas divMod does quite a bit more work. So if you are in a speed-critical section and working on positive numbers only, quotRem is the way to go.

A simple example where it would matter is testing if an integer is even or odd.

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

Note, of course, you could avoid thinking about these issues by just defining odd in this way:

let odd x = x `rem` 2 /= 0
odd 1 // True
odd (-1) // True

In general, just remember that, for y > 0, x mod y always return something >= 0 while x rem y returns 0 or something of the same sign as x.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!