[squeak-dev] FloatConstants?

Chris Muller asqueaker at gmail.com
Wed Dec 17 19:23:39 UTC 2014


On Wed, Dec 17, 2014 at 12:55 PM, Eliot Miranda <eliot.miranda at gmail.com> wrote:
> Hi Chris,
>
> On Dec 17, 2014, at 9:17 AM, Chris Muller <asqueaker at gmail.com> wrote:
>
>> On Wed, Dec 17, 2014 at 12:20 AM, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>>> Hi Chris,
>>>
>>> On Dec 16, 2014, at 7:24 PM, Chris Muller <asqueaker at gmail.com> wrote:
>>>
>>>> I wish to access some of the Float constants without a message send.
>>>
>>> I'm curious.  Why?
>>
>> Speed.  I need a fast map of the 32-bit Float range to unsigned 32-bit
>> integer range such that comparisons within the integer range are
>> consistent with comparisons of their floats.

Ah, I can see how my wording created an ambiguous meaning..

> So am I right in thunking that you want that if the Float has an integer equivalent the float and integer have the same hashKey32 and if they don't, you don't care as long as the hash is well-distributed?

No I meant that I need to pickle Floats as an 32-bit Integer, but
while in their pickled Integer state, I need to run #> and #<
comparisons against other pickled Floats (e.g., as their Integer
representation) and need those comparisons to produce the same results
as if they were still in their Float state.

For example, the reason I cannot simply use asIEEE32Bit is because
negative floats have a high-order bit set, and so the pickled
represetnations don't compare correctly:

  -4.321 asIEEE32Bit < 1.2345 asIEEE32Bit   "false"  <--- I need true

32-bit unsigned so I made -Infinity to be 0, +Infinity to be (2^32)-1.
But since NaN needs representation too, I decided to put it at the
top, so I bumped +Infinity down to (2^32)-2..

> If so why not...
>
> Float>>hashKey32
>     | trunc |
>     trunc := self truncated.
>     ^self = trunc
>         ifTrue: [trunc]
>         ifFalse: [(self at: 1) bitXor: (self at: 2)]
>
> ?
>> Loosely:
>>
>>     -Infinity ---------------------- Zero ------------------------
>> +Infinity    |   NaN
>>          0 ------------------------- (2^31) ----------------------- 2^32
>>
>> Here is the method I came up with to do this conversion:
>>
>>          Float>>#hashKey32
>>               self == NegativeInfinity ifTrue: [ ^ 0 ].
>>               self == Infinity ifTrue: [ ^ 4294967294 ].
>>               self isNaN ifTrue: [ ^ 4294967295 ].
>>               self == NegativeZero ifTrue:  [ ^ 2147483650 ].
>>               "Smallest to largest negative IEEE 32-bit floats range
>> from  (2147483649 to: 4286578687), so invert that range."
>>               self negative ifTrue: [ ^ (4286578687 - self
>> asIEEE32BitWord) + 1 ].
>>               "We're positive.  IEEE positives range from (0 to: 2139095039)."
>>               ^ self asIEEE32BitWord + 2147483651
>>
>> Since I need _maximum_ speed, I do not wish the check for Infinites
>> and NaN's, the special cases, to require a message send..
>>
>>>> Would anyone mind if I moved the class-vars defined in Float into a
>>>> new Pool called "FloatConstants", so I may import them and write
>>>> myFloat == NaN?
>>>
>>> Instead simply define the pool and initialize it.  IMO it is your own business if you want to define such a pool but it does not need to be in the base image.  The existing access has worked just fine so far.
>>
>> Since I'm able to put my method within the same scope as the Float
>> class-var constants, I guess I don't need the FloatConstants pool
>> afterall, but since these are constants that extend beyond the Milky
>> Way to the known ends of the physical universe, I can't understand why
>> you want access to them restricted to such a tiny bottle.
>> FloatConstants would allow better brevity and elegance of code.  Why
>> should everyone be required to write "Float pi" over and over instead
>> of simply "Pi"?
>>
>


More information about the Squeak-dev mailing list