16

I'm trying to check if a variable I have is equals to NaN in my Ruby on Rails application.

I saw this answer, but it's not really useful because in my code I want to return 0 if the variable is NaN and the value otherwise:

 return (average.nan ? 0 : average.round(1))

The problem is that if the number is not a NaN I get this error:

NoMethodError: undefined method `nan?' for 10:Fixnum

I can't check if the number is a Float instance because it is in both cases (probably, I'm calculating an average). What can I do? It is strange only to me that a function to check if a variable is equals to NaN is avaible only to NaN objects?

Nakilon
  • 34,866
  • 14
  • 107
  • 142
ste
  • 3,087
  • 5
  • 38
  • 73

3 Answers3

36

Quickest way is to use this:

under_the_test.to_f.nan? # gives you true/false e.g.:
123.to_f.nan? # => false
(123/0.0).to_f.nan? #=> true

Also note that only Floats have #nan? method defined on them, that's the reason why I'm using #to_f in order to convert result to float first.

Tip: if you have integer calculation that potentially can divide by zero this will not work:

(123/0).to_f.nan? 

Because both 123 and 0 are integers and that will throw ZeroDivisionError, in order to overcome that issue Float::NAN constant can be useful - for example like this:

return Float::NAN if divisor == 0
return x / divisor
river
  • 774
  • 5
  • 16
  • 2
    This solved my problem but in my console, this: (123/0.0).to_f.nan? equals false Ruby: 2.2.3p173 Rails: 4.2.5.1 – ste Jul 12 '16 at 14:48
  • 1
    Your division by zero example == NaN example is bad practice. According to standards defined by `IEEE754`: `0.0 / 0 == Float::NAN` and `1.0/0 == Float::INFINITY`. But ruby already complies to the standard, so there is no need to hand-craft your own `return` statements. – Tom Lord Aug 30 '17 at 08:28
  • Downvoted because the code is incorrect--currently in Ruby, dividing an `Integer` by a`Float` such as in `(123/0.0)` will result in a `Float::INFINITY`, ***NOT*** `Float::NAN` which is what the question asked about. – Steve Benner Apr 07 '22 at 06:38
2

I found this answer while duckducking for something that is neither NaN nor Infinity (e.g., a finite number). Hence I'll add my discovery here for next googlers.

And as always in ruby, the answer was just to type my expectation while searching in the Float documentation, and find finite?

n = 1/0.0 #=> Infinity
n.nan? #=> false
n.finite? #=> false
Ulysse BN
  • 10,116
  • 7
  • 54
  • 82
  • It works fine only for NaN. Suppose you have to check a variable which can either be number or NaN, In this case for example a `valid_number.nan?` throws error. So as per @river 's answer it's best to add `.to_f` before checkin `.nan?` – Nithin S Jul 15 '22 at 12:19
1

The best way to avoid this kind of problem is to rely on the fact that a NaN isn't even equal to itself:

a = 0.0/0.0
a != a
# -> True !

This is likely not going to be an issue with any other type.

Vincent Fourmond
  • 3,038
  • 1
  • 22
  • 24