Incorrect -0.0.hash - Ruby bug.

T

Thomas B.

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

In the rdoc to Object#hash we read
(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.
 
J

John W Higgins

[Note: parts of this message were removed to make it a legal post.]

Morning Thomas,

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

In the rdoc to Object#hash we read
(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
 
J

James Coglan

[Note: parts of this message were removed to make it a legal post.]

2009/7/22 John W Higgins said:
Morning Thomas,



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?
 
R

Robert Dober

Morning Thomas,
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 =3D> 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


--=20
Toutes les grandes personnes ont d=92abord =E9t=E9 des enfants, mais peu
d=92entre elles s=92en souviennent.

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

[Antoine de Saint-Exup=E9ry]
 
T

Thomas B.

James said:
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 :)
 
L

lith

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,733
Latest member
LonaMonzon

Latest Threads

Top