Use isNaN when checking for NaN

When checking whether a number is NaN, use isNaN rather than == NaN.

Reason

By specification, NaN is not equal to anything, not even itself:

Double.NaN == Double.NaN
// res0: Boolean = false

Use isNaN instead, which is meant for just this task:

Double.NaN.isNaN
// res1: Boolean = true

Exception to the rule

There’s one scenario in which you shouldn’t use isNaN: if you’re working with a lot of numbers and need to manually validate each one of them. isNaN can be a bit slow - it’s been much improved in 2.12+, but still has a small cost.

If you identify this as a bottleneck, you always have the option of being clever. The two following methods produce the same result, but the second one is faster:

def slowFilterNaN(ds: Seq[Double]): Seq[Double] = ds.filter(d => !d.isNaN)

def fastFilterNaN(ds: Seq[Double]): Seq[Double] = ds.filter(d => d == d)

Note that this is an optimisation, and one that is sure to mystify some readers. It should only be used when a bottleneck is identified, as the runtime gain is otherwise guaranteed to be lower than the human cost of explaining it over and over again.

Checked by

LinterRule
Scala Linter
Scapegoat
  • NanComparison