Reported by mark.engelberg, Dec 28, 2008
mod (modulo) is similar to rem, but the result will always have the same
positive/negative sign as the second input:
(mod 2 5) -> 2
(mod 2 -5) -> -3
(mod -2 5) -> 3
(mod -2 -5) -> -2
Note that rem always has a result whose sign matches the first input:
(rem 2 5) -> 2
(rem 2 -5) -> 2
(rem -2 5) -> -2
(rem -2 -5) -> -2
So mod and rem yield the same answer if both inputs are positive, or both
are negative. However, when the signs are mixed, they differ.
Sample code:
(defn mod [a b]
(if (or (< a 0 b) (< b 0 a))
(+ (rem a b) b)
(rem a b)))
Comment 1 by achim.passen, Dec 29, 2008
A patch that adds mod and sgn
mod-sgn.diff
6.9 KB Download
Comment 2 by richhickey, Jan 07, 2009
hmm... Mark's sample code looks much simpler - anything wrong with it?
Comment 3 by achim.passen, Jan 08, 2009
Not at all, it's functionally equivalent. I implemented it in Java mainly to be consistent with the other basic math
op implementations. The Java version seems to be a tick faster (~500ms vs ~600ms on 100000 pairs of
randomly typed random numbers here).
Attached is a simplified patch which adds LongOps support and gets rid of signum.
r1205+mod.diff
4.9 KB Download
Comment 4 by richhickey, Jan 22, 2009
Added Mark's version, SVN 1227 - thanks!
Status: Fixed
Comment 6 by timothypratley, Feb 12, 2009
Yet another 'fixed' version:
(mod 9 -3) -> 0
(mod 4.5 2) -> 0.5
mod-fix.patch
759 bytes Download
Comment 7 by richhickey, Feb 23, 2009
patch applied - svn 1302 - thanks!
Converted from http://www.assembla.com/spaces/clojure/tickets/27
Attachments:
mod-fix.patch - https://www.assembla.com/spaces/clojure/documents/c5Ksw6w3er3PSteJe5afGb/download/c5Ksw6w3er3PSteJe5afGb
r1205mod.diff - https://www.assembla.com/spaces/clojure/documents/c5KveQw3er3PSteJe5afGb/download/c5KveQw3er3PSteJe5afGb
mod-sgn.diff - https://www.assembla.com/spaces/clojure/documents/c5KxFww3er3PSteJe5afGb/download/c5KxFww3er3PSteJe5afGb