[squeakdev] [Cuisdev] 32 vs 64 bits and large integer hash
Juan Vuletich
juan at jvuletich.org
Wed Nov 21 21:37:33 UTC 2018
Hi Eliot,
On Cuis I have been recently working on hash consistency for numeric
types, making same value (or different values that compare as equal due
to rounding) answer same hash regardless of class. But I have missed the
SmallInteger / LargeInteger consistency across 32 / 64 bits images.
Thanks! Fixes for Cuis now at GitHub repo. In particular, it is
necessary for the following to answer the same values in 32 and 64 bits
(it wasn't the case!):
largeInteger := (LargePositiveInteger new: 4)
digitAt: 1 put: 1;
digitAt: 2 put: 2;
digitAt: 3 put: 3;
digitAt: 4 put: 4;
yourself.
smallInteger := largeInteger normalize.
float := smallInteger asFloat.
boxedFloat := BoxedFloat64 new basicAt: 1 put: (float basicAt: 1);
basicAt: 2 put: (float basicAt: 2); yourself.
{largeInteger class. smallInteger class. float class. boxedFloat class.
largeInteger hash. smallInteger hash. float hash. boxedFloat hash } print.
largeInteger _ (LargePositiveInteger new: 4)
digitAt: 1 put: 1;
digitAt: 2 put: 2;
digitAt: 3 put: 3;
digitAt: 4 put: 80;
yourself.
smallIntIn64ButLargeIntIn32Bits := largeInteger normalize.
float := smallIntIn64ButLargeIntIn32Bits asFloat.
boxedFloat := BoxedFloat64 new basicAt: 1 put: (float basicAt: 1);
basicAt: 2 put: (float basicAt: 2); yourself.
{largeInteger class. smallIntIn64ButLargeIntIn32Bits class. float class.
boxedFloat class.
largeInteger hash. smallIntIn64ButLargeIntIn32Bits hash. float hash.
boxedFloat hash } print.
Note that I also included consistency between unnormalized
LargeIntegers in the SmallInteger range (just in case).
On 11/21/2018 3:45 PM, Eliot Miranda via Cuisdev wrote:
> Hi All,
>
> right now we have the following definition of
> Large(Positive)Integer>>hash:
>
> hash
> ^ByteArray hashBytes: self startingWith: self species hash
>
> which means that for all integers outside of the 32bit SmallInteger
> range (2 ^ 30 to 2 ^ 30  1), the 32bit system and the 64bit system
> answer different values for hash.
>
> e.g. in 64 bits: (2 raisedTo: 30) hash 1073741824
> but in 32 bits: (2 raisedTo: 30) hash 230045764
>
> This is unsatisfactory. I propose changing
> Large(Positive)Integer>>hash to
>
> hash
> ^self digitLength <= 8
> ifTrue: [self]
> ifFalse: [ByteArray hashBytes: self startingWith: self species hash]
>
>
> P.S. Note that this will not break Float hash, which is defined as
>
> Float>>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)
>
> P.P.S. I *think* that "(self isFinite and: [self fractionPart = 0.0])"
> is equivalent to "self  self = self fractionPart" ;)
>
> _,,,^..^,,,_
> best, Eliot
>
Cheers,

Juan Vuletich
www.cuissmalltalk.org
https://github.com/CuisSmalltalk/CuisSmalltalkDev
https://github.com/jvuletich
https://www.linkedin.com/in/juanvuletich75611b3
@JuanVuletich
 next part 
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeakdev/attachments/20181121/8ec6c291/attachment.html>
More information about the Squeakdev
mailing list
