<div dir="ltr"><div>This code is acrobatically converting<br>single precision float bits -> double precision float bits<br><br>Frankly, it would be much easier conceptually to convert via<br>single precision float bits -> abstract float representation (sign, exponent , significand) -> double precision bits<br>Indeed, the second conversion is more than easy via (significandAsInteger asFloat timesTwoPower: exponent - bias).<br></div>It might even be faster than these LargeInteger arithmetics (at least until 64bits spur)<br></div><div class="gmail_extra"><br><div class="gmail_quote">2014-12-23 23:51 GMT+01:00 <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Nicolas Cellier uploaded a new version of Kernel to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Kernel-nice.892.mcz" target="_blank">http://source.squeak.org/trunk/Kernel-nice.892.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Kernel-nice.892<br>
Author: nice<br>
Time: 23 December 2014, 11:50:48.613 pm<br>
UUID: 85017561-ba41-4e1f-9c6b-37f97730b5ea<br>
Ancestors: Kernel-eem.891<br>
<br>
Fix Float class>>fromIEEE32Bit: in the case of gradual underflow again...<br>
<br>
Details:<br>
<br>
A single precision (32bits) float gradual underflow is of the form<br>
biased exponent = 0 (-127 unbiased, but true value to take into account is -126)<br>
significand of the form 0.bbb....b (23 bit after the floating point, no implied 1)<br>
<br>
Once converted to double precision, this will not underflow...<br>
<br>
So we must shift the significand left until the highest bit pass left of the floating point :<br>
for example 0.001b...b ==> 1.b...b000<br>
adjust the exponent (which is -126) by same number of shift (-129 in this example since there are 3 shifts)<br>
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.<br>
<br>
=============== Diff against Kernel-eem.891 ===============<br>
<br>
Item was changed:<br>
----- Method: Float class>>fromIEEE32Bit: (in category 'instance creation') -----<br>
fromIEEE32Bit: word<br>
"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."<br>
<br>
| sign mantissa exponent newFloat delta |<br>
word negative ifTrue: [^ self error:'Cannot deal with negative numbers'].<br>
word = 0 ifTrue: [^ Float zero].<br>
sign := word bitAnd: 16r80000000.<br>
word = sign ifTrue: [^self negativeZero].<br>
<br>
exponent := ((word bitShift: -23) bitAnd: 16rFF) - 127.<br>
mantissa := word bitAnd: 16r7FFFFF.<br>
<br>
exponent = 128 ifTrue:["Either NAN or INF"<br>
mantissa = 0 ifFalse:[^ Float nan].<br>
sign = 0<br>
ifTrue:[^ Float infinity]<br>
ifFalse:[^ Float negativeInfinity]].<br>
<br>
exponent = -127 ifTrue: [<br>
"gradual underflow (denormalized number)<br>
Remove first bit of mantissa and adjust exponent"<br>
delta := mantissa highBit.<br>
+ mantissa := (mantissa bitAnd: (1 bitShift: delta - 1) - 1) bitShift: 24 - delta.<br>
- mantissa := (mantissa bitShift: 1) bitAnd: (1 bitShift: delta) - 1.<br>
exponent := exponent + delta - 23].<br>
<br>
"Create new float"<br>
newFloat := self new: 2.<br>
newFloat basicAt: 1 put: ((sign bitOr: (1023 + exponent bitShift: 20)) bitOr: (mantissa bitShift: -3)).<br>
newFloat basicAt: 2 put: ((mantissa bitAnd: 7) bitShift: 29).<br>
^newFloat!<br>
<br>
<br>
</blockquote></div><br></div>