On Sun, Oct 30, 2011 at 10:02, bOR_ <boris.sch...@gmail.com> wrote:
> Hi all,
> Ran into something unexpected with "max".
> user> (sd-age-female 13)
>
>
> [10 NaN 0.746555245613119]
>
>
> user> (apply max (sd-age-female 13))
>
> 0.746555245613119

TL;DR: Don't expect sensible answers when NaN is involved.

The implementation of max in Clojure core assumes that it's possible
to compare the things it is given and get consistent results.

clojure.core:
#
#   (defn max
#     "Returns the greatest of the nums."
#     {:added "1.0"
#      :inline-arities >1?
#      :inline (nary-inline 'max)}
#     ([x] x)
#     ([x y] (. clojure.lang.Numbers (max x y)))
#     ([x y & more]
#      (reduce1 max (max x y) more)))

clojure.lang.Numbers:
#
#   static public double max(double x, double y){
#       if(x > y){
#           return x;
#       } else {
#           return y;
#       }
#   }

This doesn't turn out to be the case with IEEE floating point numbers
because of the behavior of NaN, as mandated by the standard.

For every number that is not NaN, the world works as we expect:

a < b && b < c implies a < c
a < b implies !(a >= b)
a < b implies b > a
a == b implies b == a

But, adding NaN to the mix changes all that. NaN is like a great big
black hole for truth. All of these are false:

(NaN == NaN)
(NaN < b)
(NaN >= b)
...

http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.4
#
# An operation that overflows produces a signed infinity, an operation
# that underflows produces a denormalized value or a signed zero, and an
# operation that has no mathematically definite result produces NaN. All
# numeric operations with NaN as an operand produce NaN as a result. As
# has already been described, NaN is unordered, so a numeric comparison
# operation involving one or two NaNs returns false and any !=
# comparison involving NaN returns true, including x!=x when x is NaN.

So, in your example (max [10 NaN 0.74]) what happens is this:

  - (max 10 NaN) discovers that (10 > NaN) -> false, therefore
    NaN is chosen as the "max" of the first two is NaN.

  - (max NaN 0.74) discovers that (NaN > 0.74) -> false, therefore
    0.74 is the maximum.

// Ben

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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