ruby on rails how to deal with NaN
Ruby on-RailsRubyRuby on-Rails-3Ruby on-Rails-3.2Ruby on-Rails-3.1Ruby on-Rails Problem Overview
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
Ruby on-Rails Solutions
Solution 1 - Ruby on-Rails
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)
Solution 2 - Ruby on-Rails
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