[squeakdev] FloatConstants?
Nicolas Cellier
nicolas.cellier.aka.nice at gmail.com
Tue Dec 23 22:10:52 UTC 2014
OK, I got it, the mantissa was not shifted correctly in case of underflow...
I'll publish as soon as I can get an updated trunk.
20141223 22:58 GMT+01:00 Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com>:
> Chris, this is a case of gradual underflow, and it seems like it is not
> handled correctly in Float class>>fromIEEE32Bit: .
> Since the method has my initials, I'll try to sort out what the mess is...
>
> 20141223 21:50 GMT+01:00 Chris Muller <asqueaker at gmail.com>:
>
>> On Mon, Dec 22, 2014 at 3:59 AM, Bert Freudenberg <bert at freudenbergs.de>
>> wrote:
>> > On 22.12.2014, at 00:13, Levente Uzonyi <leves at elte.hu> wrote:
>> >>
>> >> ConverterFloatArray at: 1 put: self; basicAt: 1.
>> >
>> > Any reason not to use this in #asIEEE32BitWord? Endianness?
>> Archdependency?
>> >
>> > I see, it's not threadsafe. This would be:
>> >
>> > (FloatArray new: 1) at: 1 put: self; basicAt: 1.
>> >
>> > Might still be faster?
>>
>> Yes. Since creation of a oneelement FloatArray every time did not
>> adversely affect performance of Levente's too significantly (only 3.7X
>> instead of 4.0X faster), I decided it was worth the cost of the
>> allocation than to worry about concurrency. So I ended up with
>> Levente's latest except I cannot risk a calculation ending up 0.0, so
>> I have to account for it too. And, NaN too. Thus:
>>
>> hashKey32
>>  bits 
>> self = NegativeInfinity ifTrue: [ ^ 0 ].
>> self = Infinity ifTrue: [ ^ 4294967294 ].
>> self = NaN ifTrue: [ ^ 4294967295 ].
>> self = NegativeZero ifTrue: [ ^ 2147483651 ].
>> bits := (FloatArray new: 1) at: 1 put: self; basicAt: 1.
>> self < 0.0 ifTrue: [ ^ 4286578688  bits ].
>> ^ 2147483651 + bits
>>
>> Since there are not a full 32bits worth of IEEE 32bit floats (e.g.,
>> several thousand convert to NaN), it might be wise to move +Infinity
>> and NaN _down_ a bit from the very maximum, for better continuity
>> between the float and integer number lines, or for potential future
>> specialcase needs..?
>>
>> In any case, I wanted to at least see if what we have, above, works
>> for every 32bit IEEE float. To verify that, I enumerated all Floats
>> in numerical order from Infinity to +Infinity by creating them via
>> #fromIEEE32BitFloat: from the appropriate ranges.
>>
>> It hit a snag at 2151677948. Check this out:
>>
>>  this next 
>> this := Float fromIEEE32Bit: 2151677949.
>> next := Float fromIEEE32Bit: 2151677948.
>> self
>> assert: next > this ;
>> assert: ((FloatArray new: 1) at: 1 put: (next); basicAt: 1)
>> > ((FloatArray new: 1) at: 1 put: (this); basicAt: 1)
>>
>> As I thought, the representations between IEEE floats and FloatArray
>> floats are differentenough that their precisions align differently
>> onto the 32bit map for these two floats. IEEE's are preciseenough
>> to distinguish these two floats, FloatArray representations are not.
>>
>> That these guys are considered "equal" by the FloatArray is actually
>> good enough for my indexing requirement, but now I'm looking at the
>> primfail code for FloatArray:
>>
>> at: index
>> <primitive: 'primitiveAt' module: 'FloatArrayPlugin'>
>> ^Float fromIEEE32Bit: (self basicAt: index)
>>
>> If this or the #at:put: primitive were to ever fail on the storage
>> (at:put:) exclusiveor the access (at:) side, then it appears
>> FloatArray itself would retrieve a value different than was stored..!
>>
>>
>
 next part 
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeakdev/attachments/20141223/a6cfc65a/attachment.htm
More information about the Squeakdev
mailing list
