When is the difference between quotRem and divMod helpful?

From the haskell report:

The class quot, rem, div, and mod methods satisfy these laws if y is not equal to zero:

(x `quot` y)*y + (x `rem` y) == x (x `div` y)*y + (x `mod` y) == x 

quot is a whole division truncated to zero, and the result of the div truncated to negative infinity.

For example:

 Prelude> (-12) `quot` 5 -2 Prelude> (-12) `div` 5 -3 

What are some examples of where the difference between how the result is truncated matters?

+34
haskell division
Dec 04 '08 at 6:29
source share
3 answers

Many languages ​​have a "mod" or "%" operator that gives the remainder after division, truncated to 0; e.g. C, C ++ and Java, and possibly C #, will say:

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

Haskell quot and rem are intended to simulate this behavior. I can imagine that compatibility with the release of some C program may be desirable in some far-fetched situation.

Haskell div and mod , and then Python / and%, follow the agreement of mathematicians (at least number theorists), always truncating down division (not in the 0 direction - to negative infinity), so the remainder is always non-negative. So in Python

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

The Haskell div and mod follow this behavior.

+35
Dec 04 '08 at 7:52
source share

This is not quite the answer to your question, but in GHC on x86 quotRem on Int will compile up to one machine command, while divMod does a bit more work. Therefore, if you are in a critical critical section and only work with positive numbers, quotRem is the way to go.

+23
Dec 04 '08 at 22:53
source share

A simple example where it matters is testing if the 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 that you, of course, may not think about these issues by simply defining the odd ones 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 , and x rem y returns 0 or something similar to the x icon.

+6
Dec 04 '08 at 7:00
source share



All Articles