ANSI, =, hash, Integer, Float

Richard A. O'Keefe ok at cs.otago.ac.nz
Tue Dec 17 01:27:17 UTC 2002


I've been struggling with the ANSI Smalltalk standard.

ANSI stipulates, and Smalltalk books I've read said this before,
that you should define #= and #hash _together_ so that

    x = y   implies  x hash = y hash.

So far so good.  BUT

    0 = 0.0   => true   0 hash   => 0   0.0 hash => 0
    1 = 1.0   => true   1 hash   => 1   1.0 hash => 61440
    1/2 = 0.5 => true  (1/2)hash => 3   0.5 hash => 57344

    a := Set with: 1.
    a includes: 1.0         => false
    a asArray includes: 1.0 => true

I can actually see a way to make the hashes of numbers mutually
consistent:

    Float hash => if the value is integral and in the SmallInteger
                  range then use the hash of the corresponding
                  SmallInteger, otherwise use what's currently used.

    Large{Positive,Negative}Integer and Fraction => when the number
                  is created, compute self asFloat hash and stuff the
                  bits somewhere inside; when the hash is wanted,
                  pull out those bits again.

Dealing with the three Float{E,D,Q} sizes envisaged by ANSI would make
this even hairier.

Does any existing Smalltalk actually have number hashes that are
consistent with #= *even between different classes*?

>From the fact that this problem seems to have been around for 20+ years,
I surmise that people _don't_ make a habit of using rational numbers
(*Integer, Fraction) and Floats as keys in the same collections.




More information about the Squeak-dev mailing list