# Incorrect -0.0.hash - Ruby bug

**URL:** <https://www.ruby-forum.com/t/incorrect-0-0-hash-ruby-bug/172514>\
**Category:** Ruby\
**Created:** [July 22, 2009, 6:24pm UTC](https://www.ruby-forum.com/t/incorrect-0-0-hash-ruby-bug/172514 "2009-07-22T18:24:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![tbaustert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ecae2f/32.png) [@tbaustert](https://www.ruby-forum.com/u/tbaustert)\
**Post date:** [July 22, 2009, 6:24pm UTC](https://www.ruby-forum.com/t/incorrect-0-0-hash-ruby-bug/172514/1 "2009-07-22T18:24:21Z")

</div>

Hello. I just found a bug in Ruby, version 1.9.1p0, Windows.

In the rdoc to Object#hash we read  
([class Object - RDoc Documentation](http://ruby-doc.org/core/classes/Object.html#M000337)):

“This function must have the property that a.eql?(b) implies a.hash ==  
b.hash.”

Now see:

irb(main):214:0\> z=0.0  
=\> 0.0  
irb(main):215:0\> nz=-0.0  
=\> -0.0  
irb(main):216:0\> z.eql?(nz)  
=\> true  
irb(main):217:0\> z.hash  
=\> 1041500564  
irb(main):218:0\> nz.hash  
=\> -434138511

So the class Float does not fully follow the #hash contract. Well, isn’t  
that strange?

TPR.

---

<div class="post-metadata">

**Author:** ![tbaustert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ecae2f/32.png) [@tbaustert](https://www.ruby-forum.com/u/tbaustert)\
**Post date:** [July 22, 2009, 6:42pm UTC](https://www.ruby-forum.com/t/incorrect-0-0-hash-ruby-bug/172514/2 "2009-07-22T18:42:58Z")

</div>

Morning Thomas,

On Wed, Jul 22, 2009 at 9:24 AM, Thomas B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hello. I just found a bug in Ruby, version 1.9.1p0, Windows.
> 
> In the rdoc to Object#hash we read  
> ([class Object - RDoc Documentation](http://ruby-doc.org/core/classes/Object.html#M000337)):
> 
> “This function must have the property that a.eql?(b) implies a.hash ==  
> b.hash.”

Actually Float overrides both #eql? and #hash so the contract is not  
applicable inside that class. Is that the best option in the world?? -  
probably not - but that would make it a non bug in theory.

John

---

<div class="post-metadata">

**Author:** ![tbaustert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ecae2f/32.png) [@tbaustert](https://www.ruby-forum.com/u/tbaustert)\
**Post date:** [July 22, 2009, 6:54pm UTC](https://www.ruby-forum.com/t/incorrect-0-0-hash-ruby-bug/172514/3 "2009-07-22T18:54:06Z")

</div>

2009/7/22 John W Higgins [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> > b.hash."
> 
> Actually Float overrides both #eql? and #hash so the contract is not  
> applicable inside that class. Is that the best option in the world?? -  
> probably not - but that would make it a non bug in theory.

Is there a reason for this? Perhaps the inexact nature of Floats means  
you  
ought not to use them as hash keys?

---

<div class="post-metadata">

**Author:** ![tbaustert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ecae2f/32.png) [@tbaustert](https://www.ruby-forum.com/u/tbaustert)\
**Post date:** [July 22, 2009, 6:58pm UTC](https://www.ruby-forum.com/t/incorrect-0-0-hash-ruby-bug/172514/4 "2009-07-22T18:58:13Z")

</div>

On 7/22/09, John W Higgins [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > “This function must have the property that a.eql?(b) implies a.hash ==  
> > b.hash.”

My understanding is that this relationship shall be kept for the  
purpose of correct hash key behavior

553/60 \> ruby -v -e ‘p( {0.0 =\> 42}[-0.0] )’  
ruby 1.9.1p243 (2009-07-16 revision 24175) [i686-linux]  
nil

which is not nice.  
That said floats as hash keys are a bad idea of course because of  
equality is not very well defined anyway.

Cheers  
Robert

> Actually Float overrides both #eql? and #hash so the contract is not  
> applicable inside that class. Is that the best option in the world?? -  
> probably not - but that would make it a non bug in theory.
> 
> John

–  
Toutes les grandes personnes ont d’abord été des enfants, mais peu  
d’entre elles s’en souviennent.

All adults have been children first, but not many remember.

[Antoine de Saint-Exupéry]

---

<div class="post-metadata">

**Author:** ![tbaustert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ecae2f/32.png) [@tbaustert](https://www.ruby-forum.com/u/tbaustert)\
**Post date:** [July 22, 2009, 7:02pm UTC](https://www.ruby-forum.com/t/incorrect-0-0-hash-ruby-bug/172514/5 "2009-07-22T19:02:57Z")

</div>

James C. wrote:

> Is there a reason for this? Perhaps the inexact nature of Floats means  
> you  
> ought not to use them as hash keys?

In my program it’s very convenient to use float vectors as keys because  
I create a graph where points (vertices) are calculated numerically as  
cross points of lines and so on (that’s why I get -0.0 from time to  
time). I round the floats to 8 decimal digits, and added a quick fix for  
the hash:

alias :hash\_orig :hash  
def hash  
eql?(0.0) ? 0.0.hash\_orig : hash\_orig  
end

and it works like it should, so I think it was a good idea to use them  
as keys 🙂

---

<div class="post-metadata">

**Author:** ![tbaustert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ecae2f/32.png) [@tbaustert](https://www.ruby-forum.com/u/tbaustert)\
**Post date:** [July 22, 2009, 7:25pm UTC](https://www.ruby-forum.com/t/incorrect-0-0-hash-ruby-bug/172514/6 "2009-07-22T19:25:44Z")

</div>

> Actually Float overrides both #eql? and #hash so the contract is not  
> applicable inside that class. Is that the best option in the world?? -  
> probably not - but that would make it a non bug in theory.

I’d assume it overrides both methods in order to fulfill the contract  
not to break it. Contract are there so that people can rely on it.  
Breaking it is an error.
