[squeak-dev] The Trunk: Kernel-nice.892.mcz
Nicolas Cellier
nicolas.cellier.aka.nice at gmail.com
Tue Dec 23 23:04:38 UTC 2014
This code is acrobatically converting
single precision float bits -> double precision float bits
Frankly, it would be much easier conceptually to convert via
single precision float bits -> abstract float representation (sign,
exponent , significand) -> double precision bits
Indeed, the second conversion is more than easy via (significandAsInteger
asFloat timesTwoPower: exponent - bias).
It might even be faster than these LargeInteger arithmetics (at least until
64bits spur)
2014-12-23 23:51 GMT+01:00 <commits at source.squeak.org>:
> Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
> http://source.squeak.org/trunk/Kernel-nice.892.mcz
>
> ==================== Summary ====================
>
> Name: Kernel-nice.892
> Author: nice
> Time: 23 December 2014, 11:50:48.613 pm
> UUID: 85017561-ba41-4e1f-9c6b-37f97730b5ea
> Ancestors: Kernel-eem.891
>
> Fix Float class>>fromIEEE32Bit: in the case of gradual underflow again...
>
> Details:
>
> A single precision (32bits) float gradual underflow is of the form
> biased exponent = 0 (-127 unbiased, but true value to take into account is
> -126)
> significand of the form 0.bbb....b (23 bit after the floating point, no
> implied 1)
>
> Once converted to double precision, this will not underflow...
>
> So we must shift the significand left until the highest bit pass left of
> the floating point :
> for example 0.001b...b ==> 1.b...b000
> adjust the exponent (which is -126) by same number of shift (-129 in this
> example since there are 3 shifts)
> then remove the leading bit left of floating point - it is already taken
> into account as the implied 1 now that we do not underflow.
>
> =============== Diff against Kernel-eem.891 ===============
>
> Item was changed:
> ----- Method: Float class>>fromIEEE32Bit: (in category 'instance
> creation') -----
> fromIEEE32Bit: word
> "Convert the given 32 bit word (which is supposed to be a positive
> 32bit value) from a 32bit IEEE floating point representation into an actual
> Squeak float object (being 64bit wide). Should only be used for conversion
> in FloatArrays or likewise objects."
>
> | sign mantissa exponent newFloat delta |
> word negative ifTrue: [^ self error:'Cannot deal with negative
> numbers'].
> word = 0 ifTrue: [^ Float zero].
> sign := word bitAnd: 16r80000000.
> word = sign ifTrue: [^self negativeZero].
>
> exponent := ((word bitShift: -23) bitAnd: 16rFF) - 127.
> mantissa := word bitAnd: 16r7FFFFF.
>
> exponent = 128 ifTrue:["Either NAN or INF"
> mantissa = 0 ifFalse:[^ Float nan].
> sign = 0
> ifTrue:[^ Float infinity]
> ifFalse:[^ Float negativeInfinity]].
>
> exponent = -127 ifTrue: [
> "gradual underflow (denormalized number)
> Remove first bit of mantissa and adjust exponent"
> delta := mantissa highBit.
> + mantissa := (mantissa bitAnd: (1 bitShift: delta - 1) - 1)
> bitShift: 24 - delta.
> - mantissa := (mantissa bitShift: 1) bitAnd: (1 bitShift:
> delta) - 1.
> exponent := exponent + delta - 23].
>
> "Create new float"
> newFloat := self new: 2.
> newFloat basicAt: 1 put: ((sign bitOr: (1023 + exponent bitShift:
> 20)) bitOr: (mantissa bitShift: -3)).
> newFloat basicAt: 2 put: ((mantissa bitAnd: 7) bitShift: 29).
> ^newFloat!
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20141224/12456a73/attachment.htm
More information about the Squeak-dev
mailing list
|