Mantis - Squeak
Viewing Issue Advanced Details
3133 Kernel minor always 02-27-06 12:21 07-23-06 12:49
pmm  
MarcusDenker  
normal  
closed  
fixed  
none    
none 3.9  
0003133: [BUG][FIX] Float>>#asIEEE32BitWord and #fromIEEE32Bit:
Float>>#asIEEE32BitWord and #fromIEEE32Bit: converte a Float to a 32bit IEEE 754 word and vice versa.

I quote from the Float class comment (adjusted for 32bit):

sign 1 bit
exponent 8 bits with bias of 1023 (16r3FF) to produce an exponent
                    in the range -1023 .. +1024
            - 16r000:
                significand = 0: Float zero
                significand ~= 0: Denormalized number (exp = -1024, no hidden '1' bit)
            - 16r7FF:
                significand = 0: Infinity
                significand ~= 0: Not A Number (NaN) representation

Note: this implies there are two inifites and zeros (positive and negative).
However the two mentioned methods don't follow this specification. See the test changeset for examples. This is a problem for example if you put a Float in a FloatArray you might get a different Float back.
related to 0004264closed  SUnit tests FloatTest>>testNaN5 and Float>>testZero2 fail 
 FloatBugs-pmm.1.cs [^] (1,561 bytes) 02-27-06 12:21
 FloatIEEE754Fixes-pmm.1.cs [^] (2,071 bytes) 02-27-06 12:22
 Kernel-Float-asIEEE32BitWord-Test.1.cs [^] (5,793 bytes) 05-30-06 02:29
 Kernel-Float-asIEEE32BitWord-Patch.1.cs [^] (2,248 bytes) 05-30-06 02:30
 Kernel-Float-asIEEE32BitWord-Test.2.cs [^] (8,232 bytes) 05-30-06 03:12
 Kernel-Float-asIEEE32BitWord-Patch.2.cs [^] (3,578 bytes) 05-30-06 03:12

Notes
(0005096)
nicolas cellier   
05-29-06 23:02   
Good fix for converting Float nan.

However, this does not fix incorrect rounding mode.
Both new and older version incorrectly truncate toward zero.
They should honour IEEE default rounding mode (round to nearest even).
Note that FloatArrayPlugin primitiveAtPut does honour IEEE round to nearest even since it uses a simple C cast to (float).

I am preparing a test case and a patch...
(0005097)
nicolas cellier   
05-30-06 00:04   
I note that gradual underflow is also broken.

How to decode 32 bits float:

number is encoded seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
1 bit sign
8 bit exponent
23 bit mantissa

sign=1 - (2rs * 2).
exponent=2reeeeeeee-127

if 2reeeeeeee is 255,
  if mmmmmmmmmmmmmmmmmmmmmmm isZero, then return Infinity*sign
  else, return NaN
elseif 2reeeeeeee is 0
  this is gradual underflow (denormalized number)
  mantissa=2r0.mmmmmmmmmmmmmmmmmmmmmmm
  exponent=exponent+1
else
  this is a normalized number
  mantissa=2r1.mmmmmmmmmmmmmmmmmmmmmmm
endif

return sign*mantissa*(1.0 timesTwoPower: exponent)

Note that IEEE 754 64bits has
1 bit sign
11 bits exponent
52 bit mantissa

(0005129)
nicolas cellier   
05-30-06 02:41   
I'm tired and want to go to bed !!!
just corrected the bug, but another related method is broken...

Float class>>#fromIEEE32Bit:
does not handle gradual underflow (denormalized numbers)

This will be my last correction tonight
(0006174)
MarcusDenker   
07-23-06 12:49   
7047