Check if number is NaN
Asked Answered
I

3

17

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?

Iy answered 12/7, 2016 at 11:26 Comment(6)
this may be your answer.Sobersided
are you looking for average.nil?Wickerwork
@Wickerwork for nil check this would need to be done average.to_i.nil?Sobersided
@AAnkudovich no, you can call nil on any object, to_i on a nil object would be 0, so your example would be 0.nil?Wickerwork
i see your point sorrySobersided
What about return average.round(1) rescue 0Kala
R
38

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
Rote answered 12/7, 2016 at 11:40 Comment(3)
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.1Iy
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.Mercymerdith
Downvoted because the code is incorrect--currently in Ruby, dividing an Integer by aFloat such as in (123/0.0) will result in a Float::INFINITY, NOT Float::NAN which is what the question asked about.Taille
M
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
Marilynnmarimba answered 24/6, 2021 at 8:44 Comment(1)
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 @Rote 's answer it's best to add .to_f before checkin .nan?Expressly
T
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.

Tight answered 24/6, 2021 at 8:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.