I could not understand the difference between these two (mod
& rem
) functions.
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
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.
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.
© 2022 - 2024 — McMap. All rights reserved.