'From Pharo0.1 of 16 May 2008 [Latest update: #10201] on 4 January 2009 at 11:04:07 pm'!
"Change Set: M3374-NumberHash-Patch-nice
Date: 4 January 2009
Author: nice
This is a patch for problem of Number being equal but having different hash.
The patch is inline with modification of equal in http://bugs.squeak.org/view.php?id=3374
With these definitions: numbers are equal if and only if exactly equal
That means 0.5 = (1/2), because 0.5 representation is exactly (1/2)
But 0.1 ~= (1/10), because 0.1 asTrueFraction ~= (1/10)
hash code is modified this way:
1) Float hash is coerced to Integer hash when fractionPart = 0.0
2) Integer hash is leaved unchanged
note that hash can be negative -1 hash = -1
3) Fraction hash is coerced to Float hash if denominator is a power of two
"!
!Float methodsFor: 'comparing' stamp: 'nice 1/4/2009 18:02'!
hash
"Hash is reimplemented because = is implemented. Both words of the float are used. (The bitShift:'s ensure that the intermediate results do not become a large integer.) Care is taken to answer same hash as an equal Integer."
(self isFinite and: [self fractionPart = 0.0]) ifTrue: [^self truncated hash].
^ ((self basicAt: 1) bitShift: -4) +
((self basicAt: 2) bitShift: -4)
! !
!Fraction methodsFor: 'comparing' stamp: 'nice 1/4/2009 20:36'!
hash
"Hash is reimplemented because = is implemented.
Care is taken that a Fraction equal to a Float also have an equal hash"
| tmp |
denominator isPowerOfTwo ifTrue: [
"If denominator is a power of two, I can be exactly equal to a Float
Assume the fraction is already reduced"
tmp := self asFloat.
tmp isFinite ifTrue: [^tmp hash]].
^numerator hash bitXor: denominator hash! !