When checking whether a number is
NaN
, useisNaN
rather than== NaN
.
Note that, unlike most rules here, this one is not Scala specific. NaN
equality behaves unintuitively everywhere NaN
exists.
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
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.
Linter | Rule |
---|---|
Scala Linter | |
Scapegoat |
|