This page is no longer maintained — Please continue to the home page at www.scala-lang.org

min and max with Double.NaN

3 replies
Cybie
Joined: 2011-05-03,
User offline. Last seen 1 year 26 weeks ago.

Hi everyone!
I found something, that's an issue in my opinion.
I expected that min and max of something and NaN is equal.

min(0, Double.NaN) == max(0, Double.NaN)

In both cases I have the same problem (I can't compare NaN with a
number), so I expect the same result of min and max.

As you can see at " https://issues.scala-lang.org/browse/SI-5104 " I
already tried to solve the problem. The best solution that I can see,
would be to think arithmetically max(x,y) = avg(x ,y) + abs(x - y) /
2. But that may effect other code...

What do you think about it?

Sincerely, Daniel

David Hall 4
Joined: 2009-08-21,
User offline. Last seen 42 years 45 weeks ago.
Re: min and max with Double.NaN

You probably don't want to say == here, since Double.NaN != Double.NaN
and so the only way for the expression

min(0, Double.NaN) == max(0, Double.NaN)

to be true is if min and max are both 0...

I am not an expert on any of this stuff, but we should probably be
consistent with Java, or at least scala-internally consistent.
Currently, min is neither:

scala> (Double.NaN min 0.0)
res5: Double = 0.0

scala> java.lang.Math.min(Double.NaN,0.0)
res9: Double = NaN

scala> math.min(Double.NaN,0.0)
res10: Double = NaN

max is consistent though.

I don't know if this has any weight at all, but
http://www.itu.dk/~sestoft/javaprecisely/java-floatingpoint.pdf seems
to imply that Java and scala.math is behaving correctly according to
IEEE-754. I didn't try to dig up the spec.

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: min and max with Double.NaN
NaN spreads through every operation--which is entirely sensible given that a mathematical operation on a number and not-a-number is not defined, and therefore is not a number.  NaN also fails every condition--arguably it should return neither true nor false, but since that's all you get with a boolean, it uses "false" to mean "undefined":

scala> 0 < Double.NaN
res2: Boolean = false

scala> 0 > Double.NaN
res3: Boolean = false

scala> 0 == Double.NaN
res4: Boolean = false

If you want to check for a NaN, use one of
  x.isNaN
  Double.isNaN(x)
The former is more compact, but the latter is still often faster (given that the former creates a short-lived object, which can be avoided by the JVM's escape analysis, but it doesn't always manage to make things work as well as the method call).

This is really the only safe way to deal with NaN (other than allow them to poison all numeric computations): check with isNaN and deal accordingly.

  --Rex


On Sat, Nov 5, 2011 at 4:36 PM, Daniel <djentsch [at] zedat [dot] fu-berlin [dot] de> wrote:
Hi everyone!
I found something, that's an issue in my opinion.
I expected that min and max of something and NaN is equal.

min(0, Double.NaN) == max(0, Double.NaN)

In both cases I have the same problem (I can't compare NaN with a
number), so I expect the same result of min and max.

As you can see at " https://issues.scala-lang.org/browse/SI-5104 " I
already tried to solve the problem. The best solution that I can see,
would be to think arithmetically max(x,y) = avg(x ,y) + abs(x - y) /
2. But that may effect other code...

What do you think about it?

Sincerely, Daniel

Cybie
Joined: 2011-05-03,
User offline. Last seen 1 year 26 weeks ago.
Re: min and max with Double.NaN

Sorry, yes I meant

min(0, NaN).isNaN == max(0, NaN).isNaN

I doesn't saw the min in the math package, thanks for that.

Now I'm thinking the would be better to add an implementation for min
and max in Ordering.Double just linking to math.min and math.max.

trait DoubleOrdering extends Ordering[Double] {
def compare(x: Double, y: Double) = java.lang.Double.compare(x, y)
override def min min (x: Double, y: Double) = java.lang.Math.min
(x, y)
override def min max (x: Double, y: Double) = java.lang.Math.max
(x, y)
}

(And the same for Float)

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland