Two arguments (or maybe one argument wearing two different colored shirts) against this being a bug:
Two arguments (or maybe one argument wearing two different colored shirts) against this being a bug:
1. Numeric extends Ordering, not (merely) PartialOrdering; so under the total ordering defined by Numeric, NaN should be either greater than, less than, or equal to 1.0. Pick one.
2. Blame Java:
scala> java.lang.Double.compare(Double.NaN, 1.0)
res0: Int = 1
If I recall, IEEE spec says NaN compares false with everything including itself. The only case where it returns true is in the 'unordered' comparison.
It's been years since I looked at the IEEE spec, but if the above continues to hold, then Java got it wrong.
P.S. I've imagined writing a tongue-in-cheek PartialOrder with a
compare function that returns a Float (supporting negative, zero,
positive, or NaN results).
btw: 2.9.2 behaves differently.
Mine is not to reason why, but to switch to 2.10.
Well, if NaN gets a free pass because it breaks the rules, why not choose to construct the instance of Order such that it disagrees with the primitive operators on NaN but agrees with its own invariants?
Hello,
Conventional wisdom is that comparing +Inf, -Inf and NaN to
themselves should always yield false.
For example, compare 1.0 with (1.0 + 1e-1000), and you will be
falsely told they are equal.
Arithmetic equality != Ordering equality. Conflating the two leads to great pain and suffering.
I didn't know that Double.Infinity==Double.Infinity in Scala
, and
I'm not sure it makes sense, since inf for double is almost synonymous
for "a number too large to represent as a regular double". Consider:
scala> val x = 1e200*1e200
x: Double = Infinity
I don't understand that "no value found" metaphor, since we aren't querying.
> Makes sense to me, inasmuch as NaN is a "no value found" and you need to
> propagate that state as best you can via standard operations.
You are right that the two values are the same. The point is that
>> For example, compare 1.0 with (1.0 + 1e-1000), and you will be
>> falsely told they are equal.
>
> No, you're comparing 1.0 to 1.0 and being correctly told that they are the
> same.
comparison of double values fails to reflect mathematical reality,
since in math, (1+1e-20) is different from 1.
> Well, if NaN gets a free pass because it breaks the rules, whyIt seems like you're making a simple point with these examples, and I feel like an idiot for not getting it. Would you mind explaining what it is that you're demonstrating here?
> not choose to construct the instance of Order such that it disagrees
> with the primitive operators on NaN but agrees with its own invariants?
>
>
> val a = Array(1.0, Double.NaN, 3.0)
>
>
> var mx = a(0)
>
> i = 1
>
> while (i < a.length) { if (a(i) > mx) { mx = a(i) }; i += 1 }
>
>
> var my = Double.NaN
>
> i = 0
>
> while (i < a.length) { if (my < a(i)) { my = a(i) }; i += 1 }
>
>
> var mn = a(0)
>
> i = 1
>
> while (i < a.length) { if (a(i) < mn) { mn = a(i) }; i += 1 }
>
>
> var mm = Double.NaN
>
> i = 0
>
> while (i < a.length) { if (a(i) > mm) { mm = a(i) }; i += 1 }
>
>
> This is really powerful, and a good argument for the way things
> currently are. A little cryptic, granted, but very efficient and
> flexible.
What I see are four algorithms for finding the min and max of arrays of doubles, except that the my and mm ones get stuck on their initial Double.NaN value (and mm looks identical to my, which I assume is just a typo and not relevant to your point).
The point I was trying to make--and failed to, which is also a lesson regarding relying upon the not-entirely-trivial NaN behavior--is that you can use the NaN properties to implicitly make things work out properly without having to do extra checks.
On Wed, Jan 9, 2013 at 5:01 PM, Rex Kerr <ich...@gmail.com> wrote:
The point I was trying to make--and failed to, which is also a lesson regarding relying upon the not-entirely-trivial NaN behavior--is that you can use the NaN properties to implicitly make things work out properly without having to do extra checks.