[squeak-dev] [Cuis-dev] 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 un-normalized 
LargeIntegers in the SmallInteger range (just in case).

On 11/21/2018 3:45 PM, Eliot Miranda via Cuis-dev 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 32-bit SmallInteger 
> range (-2 ^ 30 to 2 ^ 30 - 1), the 32-bit system and the 64-bit 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.cuis-smalltalk.org
https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev
https://github.com/jvuletich
https://www.linkedin.com/in/juan-vuletich-75611b3
@JuanVuletich

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20181121/8ec6c291/attachment.html>


More information about the Squeak-dev mailing list