I spoke too soon. Apparently from the Lisp HyperSpec
mod performs the operation floor on number and divisor and returns the
remainder of the floor operation.
Which would indicate that mod1 is not consistent with LISP.
Seeing Java doesn't have a proper mod, it would seem sensible to
follow the LISP/Ruby/Python convention...

(defn mod2
  "modulus of num and div."
  [num div]
  (let [m (rem num div)]
    (cond
      (or (not (integer? num)) (not (integer? div)))
        (throw (IllegalArgumentException.
          "mod requires two integers"))
      (zero? m) 0
      (or (< num 0 div) (< div 0 num)) (+ m div)
      :else m)))

user=> (map #(mod2 % 3) (range -9 9))
(0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2)
user=> (map #(mod2 % -3) (range -9 9))
(0 -2 -1 0 -2 -1 0 -2 -1 0 -2 -1 0 -2 -1 0 -2 -1)

>>> map(lambda x: x % -3, range(-9,9) )
[0, -2, -1, 0, -2, -1, 0, -2, -1, 0, -2, -1, 0, -2, -1, 0, -2, -1]

ie: I think the original implementation simply overlooked the case
where rem div num is 0, as per floor.


Regards,
Tim.


On Feb 11, 10:46 am, Timothy Pratley <timothyprat...@gmail.com> wrote:
> Interesting!
>
> Based uponhttp://mathforum.org/library/drmath/view/52343.html
> mod might be modified to look like this
>
> (defn mod1
>   "modulus of num and div."
>   [num div]
>   (cond
>    (or (not (integer? num)) (not (integer? div)))
>      (throw (IllegalArgumentException.
>            "mod requires two integers"))
>    (< num 0 div) (- (rem num div))
>    (< div 0 num) (rem num (- div))
>    :else (rem num div)))
>
> user=> (map #(mod1 % 3) (range -9 9))
> (0 2 1 0 2 1 0 2 1 0 1 2 0 1 2 0 1 2)
>
> > [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]
>
> Notably that is still not the same as those other languages! However I
> believe it is 'correct' due to Java and Clojure's definition of div.
> Ruby and Python define integer division of or by a negative number
> differently that C and Java do. Consider the quotient -7/3. Java gives
> -2. Ruby gives -3.
>
> Regards,
> Tim.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to