Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between `mod` and `rem` in Haskell

Tags:

haskell

People also ask

What is the difference between REM and mod?

Description: mod and rem are generalizations of the modulus and remainder functions respectively. mod performs the operation floor on number and divisor and returns the remainder of the floor operation. rem performs the operation truncate on number and divisor and returns the remainder of the truncate operation.

What Is REM in Haskell?

rem is integer remainder, satisfying: (x `quot` y)*y + (x `rem` y) == x. div is integer division truncated toward negative infinity.

How does the mod function work in Haskell?

In Haskell mod takes the sign of the divisor (floored division, same as Python), while rem behaves the same way as Scheme's remainder or C's %. I prefer Scheme's way, because it was what we always used in classes when I studied maths. mod returning a negative number is just too weird.


They're not the same when the second argument is negative:

2 `mod` (-3)  ==  -1
2 `rem` (-3)  ==  2

Yes, those functions act differently. As defined in the official documentation:

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

 


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).


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.