Bug #7676

Comparison of Float::NAN in array behaves unexpectedly

Added by simonrussell (Simon Russell) over 4 years ago. Updated over 1 year ago.

Target version:
ruby -v:
ruby 1.9.3p362 (2012-12-25 revision 38607) [x86_64-linux]


It seems that two arrays containing Float::NAN will be considered equal ([Float::NAN] == [Float::NAN]), despite the fact that Float::NAN != Float::NAN.

Tested and reproduced in 1.8.7p371, 1.9.3p362, 2.0.0preview2. (This bug can be reproduced in Ruby 1.8 as well.) Results below.

1.8.7 p371

1.8.7 :001 > nan = 0.0/0.0
=> NaN
1.8.7 :002 > nan == nan
=> false
1.8.7 :003 > [nan] == [nan]
=> true

1.9.3 p362

1.9.3p362 :001 > Float::NAN == Float::NAN
=> false
1.9.3p362 :002 > [Float::NAN] == [Float::NAN]
=> true

2.0.0 preview2

2.0.0dev :001 > Float::NAN == Float::NAN
=> false
2.0.0dev :002 > [Float::NAN] == [Float::NAN]
=> true

bug-7676.patch (1.67 KB) bug-7676.patch charliesome (Charlie Somerville), 01/09/2013 11:00 PM

Related issues

Is duplicate of Ruby trunk - Bug #1720: [NaN] == [NaN] が true になるClosed2009-07-03


#1 [ruby-core:51334] Updated by charliesome (Charlie Somerville) over 4 years ago

Attached a patch fixing this issue - the pointer equality checks in recursive_equal and rb_equal should not be performed as this breaks in the case where a != a.

I'm not committing this straight away because it causes three test failures due to brittle mocks.

#2 [ruby-core:51335] Updated by ngoto (Naohisa Goto) over 4 years ago

  • Status changed from Open to Rejected

#3 [ruby-core:51336] Updated by simonrussell (Simon Russell) over 4 years ago

This isn't just Float::NAN, actually; as Charlie's patch shows, it's actually any object that always returns false from ==

1.9.3p125 :001 > class X
1.9.3p125 :002?>   def ==(other)
1.9.3p125 :003?>     false
1.9.3p125 :004?>   end
1.9.3p125 :005?> end
 => nil 
1.9.3p125 :006 > x =
 => #<X:0x00000000ba1648> 
1.9.3p125 :007 > x == x
 => false 
1.9.3p125 :008 > [x] == [x]
 => true 

Is this desirable behaviour?

#4 [ruby-core:51337] Updated by simonrussell (Simon Russell) over 4 years ago

At the very least, the documentation for Array#== should be updated to state that it first does an object identity comparison, then calls == only if the objects aren't the same instance.

#5 [ruby-core:51339] Updated by hasari (Hiro Asari) over 4 years ago

I, too, found documentation still lacking. I read #1720, and I understand the rationale for the Float::NAN case.

However, the issue still remains as Simon pointed out above. Please reopen the issue, or update the documentation to reflect the behavior more closely.

#6 [ruby-core:51340] Updated by ngoto (Naohisa Goto) over 4 years ago

  • Category set to doc
  • Status changed from Rejected to Open

#7 [ruby-core:51341] Updated by mrkn (Kenta Murata) over 4 years ago

  • Assignee set to matz (Yukihiro Matsumoto)
  • Target version set to next minor

I think this is the specification issue, so we need to confirm the mat'z thought.
Matz, how do you think about it?

#8 [ruby-core:51342] Updated by charliesome (Charlie Somerville) over 4 years ago

I understand that matz wants nan == nan to be undefined, but I think this should remain consistent within a platform, even though it is undefined between platforms.

#9 [ruby-core:56394] Updated by steveklabnik (Steve Klabnik) about 4 years ago

I would be happy to write a documentation patch for this if Matz can confirm which behavior is correct.

#10 [ruby-core:72887] Updated by dwfait (Dwain Faithfull) over 1 year ago

It appears calling eql? on array does not behave in this way:

[Float::NAN].eql? [Float::NAN]
=> false

Should we aim for consistency between these methods? Does it make sense for one to have an identity check and for the other not to?

I believe it doesn't really make sense for == to have an identity check, as the example in #3 is not how I'd expect Ruby to behave.

Also available in: Atom PDF