Difference between `mod` and `rem` in Haskell
HaskellHaskell Problem Overview
What exactly is the difference between mod
and rem
in Haskell?
Both seems to give the same results
*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
Haskell Solutions
Solution 1 - Haskell
They're not the same when the second argument is negative:
2 `mod` (-3) == -1
2 `rem` (-3) == 2
Solution 2 - Haskell
Yes, those functions act differently. As defined in the [official documentation][1]:
quot
is integer division truncated toward zero
rem
is integer remainder, satisfying:
(x `quot` y)*y + (x `rem` y) == x
div
is integer division truncated toward negative infinity
mod
is integer modulus, satisfying:
(x `div` y)*y + (x `mod` y) == x
You can really notice the difference when you use a negative number as second parameter and the result is not zero:
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
[1]: http://hackage.haskell.org/package/base-4.7.0.2/docs/Prelude.html
Solution 3 - Haskell
Practically speaking:
If you know both operands are positive, you should usually use quot
, rem
, or quotRem
for efficiency.
If you don't know both operands are positive, you have to think about what you want the results to look like. You probably don't want quotRem
, but you might not want divMod
either. The (x `div` y)*y + (x `mod` y) == x
law is a very good one, but rounding division toward negative infinity (Knuth style division) is often less useful and less efficient than ensuring that 0 <= x `mod` y < y
(Euclidean division).
Solution 4 - Haskell
In case you only want to test for divisibility, you should always use rem
.
Essentially x `mod` y == 0
is equivalent to x `rem` y == 0
, but rem
is faster than mod
.
Solution 5 - Haskell
quotRem' a b = (q, r) where
q = truncate $ (fromIntegral a / fromIntegral b :: Rational)
r = a - b * q
divMod' a b = (q, r) where
q = floor $ (fromIntegral a / fromIntegral b :: Rational)
r = a - b * q
ex:
(-3) / 2 = -1.5
(-3) `quot` 2 = truncate (-1.5) = -1
(-3) `div` 2 = floor (-1.5) = -2
(-3) `rem` 2 = -3 - 2 * (-1) = -1
(-3) `mod` 2 = -3 - 2 * (-2) = 1
3 / (-2) = -1.5
3 `quot` (-2) = truncate (-1.5) = -1
3 `div` (-2) = floor (-1.5) = -2
3 `rem` (-2) = 3 - (-2) * (-1) = 1
3 `mod` (-2) = 3 - (-2) * (-2) = -1
Solution 6 - Haskell
I cannot upload an image to explain it. But you can draw it yourself.
suppose :
X = mod(a,b) ; Y = rem(a,b)
---(-(n+1)b)---a---(-nb)---.......--(-2b)-----(-b)-----0-----b--->
X = a - [ -(n+1)b ]
so that X is always positive
Y = a - [ -nb ]
in standard documentation:
mod --> a - b.*floor(a./b).......floor is closer to negative infinity
rem --> a - b.*fix(a./b).........fix is closer to 0