ruby on rails how to deal with NaN
Asked Answered
P

2

52

I have read few posts regarding NaN but did not figure out how to deal with it in Ruby on Rails. I want to check a value if it is a NaN I want to replace it with Zero(0). I tried the following

logger.info(".is_a? Fixnum #{percent.is_a? Fixnum}")

when percent has NaN it returns me false.

I have made few changes in the logger

logger.info("Fixnum #{percent.is_a? Fixnum} percent #{percent}")

Output

Fixnum false percent 94.44444444444444
Fixnum false percent NaN
Fixnum false percent 87.0
Principal answered 3/10, 2013 at 8:34 Comment(0)
M
112

NaN is instance of Float. Use Float#nan? method.

>> nan = 0.0/0 # OR nan = Float::NAN
=> NaN
>> nan.class
=> Float
>> nan.nan?
=> true
>> nan.is_a?(Float) && nan.nan?
=> true
>> (nan.is_a?(Float) && nan.nan?) ? 0 : nan
=> 0

UPDATE

NaN could also be an instance of BigDecimal:

((nan.is_a?(Float) || nan.is_a?(BigDecimal)) && nan.nan?) ? 0 : nan

or

{Float::NAN => 0, BigDecimal::NAN => 0}.fetch(nan, nan)
Metachromatism answered 3/10, 2013 at 8:39 Comment(3)
It's also defined as a constant: Float::NAN #=> NanIoved
If you are working with the standard library, NaN could also be an instance of BigDecimal.Obstetrician
@cornflakes24, Thank you for the comment. I updated the answer accordingly.Metachromatism
P
1

The answer provided by @falsetru was helpful, but you should be careful using their last suggestion:

{Float::NAN => 0, BigDecimal::NAN => 0}.fetch(nan, nan)

Using ruby version 2.5, if I use the example they provided in irb:

>> require "bigdecimal"
=> true
>> nan = 0.0/0 # OR nan = Float::NAN
=> NaN
>> {Float::NAN => 0, BigDecimal::NAN => 0}.fetch(nan, nan)
=> NaN

You get NaN instead of the expected 0. I would use their previous suggestion instead:

((nan.is_a?(Float) || nan.is_a?(BigDecimal)) && nan.nan?) ? 0 : nan
>> require "bigdecimal"
=> true
>> nan = 0.0/0 # OR nan = Float::NAN
=> NaN
>> ((nan.is_a?(Float) || nan.is_a?(BigDecimal)) && nan.nan?) ? 0 : nan
=> 0
Polycrates answered 3/1, 2022 at 16:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.