Difference between mod and rem in Clojure
Asked Answered
K

3

16

I could not understand the difference between these two (mod & rem) functions.

Kidding answered 13/5, 2016 at 13:12 Comment(0)
N
23

Clojuredoc's example for rem describes the difference:

;; rem and mod are commonly used to get the remainder.
;; mod means Gaussian mod, so the result is always
;; non-negative.  Don't confuse it with ANSI C's %
;; operator, which despite being pronounced
;; 'mod' actually implements rem, i.e. -10 % 3 = -1.

user=> (mod -10 3)
2

user=> (rem -10 3)
-1
Nicolasanicolau answered 13/5, 2016 at 13:29 Comment(0)
E
18

mod returns the difference of the first number, and the biggest integer (possibly negative) multiple of the second number that is less than the first number:
rem is just the remainder.

For example (rem -4 3) => -1 no surprise here: -4 divided by 3 is -1 with -1 "left over".
But weirdness happens if we use mod: (mod -4 3) => 2:

  • The greatest integer multiple of 3 less than -4 is -6.
  • -4 minus -6 is 2.

So even though they usually act similarly, mod does not return the remainder, it does something more specific.

You might find these clojuredocs examples helpful.

Excretion answered 13/5, 2016 at 14:4 Comment(0)
B
2

The difference shows up with negative numbers. (rem -3 2) is -1, while (mod -3 2) is 1.

More generally, the rem function is defined to complement quot, which is integer division rounding toward zero. So this relation always holds:

(let [q (quot a b) 
      r (rem  a b)] 
  (assert (= a (+ r (* q b)))))

For example, (quot -3 2) is -1, (rem -3 2) is -1, and (+ -1 (* -1 2)) is indeed -3.

The mod function is instead defined such that the result of (mod a b) for positive b is always in the range [0,b-1], even if a is negative. This is normally what you expect from "modular arithmetic"; a repeating cycle of the same numbers forever, no matter which direction you go in.

It's especially useful in conjunction with an integer division operation which rounds down instead of toward zero (that is, if the answer is negative, the rounded answer is more negative), which Clojure unfortunately doesn't have a predefined function for. You can define your own, though:

(defn div [a b] (int (. Math floor (/ a b))))

Then (div -3 2) is -2, because -2 * 2 = -4 is the largest even multiple of 2 less than or equal to -3. (Equivalently, -2 is the largest integer less than or equal to -1.5.)

This is in fact how integer division is defined in many other languages, such as Common Lisp (the two-argument floor function), Python (the // operator), Ruby (the Integer#div method), etc.

With such a function defined, the above assertion for quot/rem also holds for div/mod:

(let [q (div a b) 
      r (mod a b)] 
  (assert (= a (+ r (* q b)))))

For example, (div -3 2) is -2, (mod -3 2) is 1, and (+ 1 (* -2 2)) is again equal to -3.

Barrie answered 9/9, 2021 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.