2

I find this behavior rather strange

> [1, 2, 3, 'a', 'b', Float::NAN].include? Float::NAN
false

I tried this then and got surprised

> Float::NAN == Float::NAN
false

So, to check for Float::NAN, I had to resort to

> [1, 2, 3, 'a', 'b', Float::NAN].any? { |i| i.is_a?(Float) && i.nan? }
true

So,

  1. Is there a better way to check for Float::NAN in an array?
  2. Why is there such a weird behavior with Float::NAN?
Mladen Jablanović
  • 43,461
  • 10
  • 90
  • 113
Lokesh
  • 2,842
  • 7
  • 32
  • 47

1 Answers1

2

To check, you can use:

[1, 2, 3, 'a', 'b', Float::NAN].any?{|item| item.respond_to?(:nan?) && item.nan?}

(or try, if you use Rails)

And as for why, take a look at What is the rationale for all comparisons returning false for IEEE754 NaN values?

Community
  • 1
  • 1
Mladen Jablanović
  • 43,461
  • 10
  • 90
  • 113
  • 1
    Excellent answer! Would this work `[1, 2, 3, 'a', 'b', Float::NAN].any? { |e| e != e } #=> true`? That is, are there any other Ruby objects `e` for which `e != 3 #=> true`? – Cary Swoveland Aug 03 '16 at 18:56
  • Good idea, but I'm afraid it would considerably increase the wtf/loc ratio. :) BTW, I have no idea whether any other class redefined `==` this way. – Mladen Jablanović Aug 03 '16 at 19:05