Processors work on ieee doubles though. An extra NaN check isn’t going to kill your performance, but boxing everything in Option is. That’s a bunch of conflicting requirements. Is min/max parametric? If so, it must request the rules of the Ordering, and for those to be consistent, you have to be able to order NaN. Choosing not to deal with NaN means either lifting in Option, which will kill your performance, or throwing, which makes for a pretty ugly interface.


For almost all purposes, IEEE 754 operations behave as if they are monadic Option[ValidDoubleValue]. x op y is equivalent to for (rx <- x; ry <- y) yield rx op ry for almost every operation save boolean ones, which append .getOrElse(false).

When you try to sort Option, the Nones all come out first; but Seq(x, y, z).sorted.last does not match the for-comprehension max in that case.

And if None is an error, well, you’re out of luck with exceptions there, too.

It’s the same issue, with the same problems. You’ve already got Option built in to IEEE754 math. Just use it. If you like it the IEEE754 way, because it’s almost isomorphic to Option[ValidDouble], pick IeeeOrdering.


The JVM specs say:

                           > The floating-point

operations of the Java Virtual Machine do not throw exceptions, trap, or
otherwise signal the IEEE 754 exceptional conditions of invalid
operation, division by zero, overflow, underflow, or inexact. The
Java Virtual Machine has no signaling NaN value.

So, if you want to have an exception for NaN, you have to add your own test, like assert(!x.isNaN).

Most algorithms that can produce NaN are numerically unstable. For example, if you have (y2-y1)/(x2-x1), not only can you zero divided by zero, but much more likely, you can get very small imprecise number divided by very small imprecise number, resulting in a valid Double with a large error. Where do your NaNs come from?