## [squeak-dev] The Trunk: Kernel-nice.605.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Jul 15 21:22:49 UTC 2011

```Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.605.mcz

==================== Summary ====================

Name: Kernel-nice.605
Author: nice
Time: 15 July 2011, 11:21:58.548 pm
UUID: 59831937-c6b3-4a5a-9f2a-a14f898e6fd7
Ancestors: Kernel-ul.604

Fix: a negative fraction asFloat should answer negativeZero when it underflows

=============== Diff against Kernel-ul.604 ===============

Item was changed:
----- Method: Fraction>>asFloat (in category 'converting') -----
asFloat
This implementation will answer the closest floating point number to
It uses the IEEE 754 round to nearest even mode
(can happen in case denominator is a power of two)"

| a b q r exponent floatExponent n ha hb hq q1 |
a := numerator abs.
b := denominator abs.
ha := a highBit.
hb := b highBit.

"If both numerator and denominator are represented exactly in floating point number,
then fastest thing to do is to use hardwired float division"
(ha < 54 and: [hb < 54]) ifTrue: [^numerator asFloat / denominator asFloat].

"Try and obtain a mantissa with 54 bits.
First guess is rough, we might get one more bit or one less"
exponent := ha - hb - 54.
exponent > 0
ifTrue: [b := b bitShift: exponent]
ifFalse: [a := a bitShift: exponent negated].
q := a quo: b.
r := a - (q * b).
hq := q highBit.

"check for gradual underflow, in which case we should use less bits"
floatExponent := exponent + hq - 1.
n := floatExponent > -1023
ifTrue: [54]
ifFalse: [54 + floatExponent + 1022].

hq > n
ifTrue: [exponent := exponent + hq - n.
r := (q bitAnd: (1 bitShift: hq - n) - 1) * b + r.
q := q bitShift: n - hq].
hq < n
ifTrue: [exponent := exponent + hq - n.
q1 := (r bitShift: n - hq) quo: b.
q := (q bitShift: n - hq) bitAnd: q1.
r := (r bitShift: n - hq) - (q1 * b)].

"check if we should round upward.
The case of exact half (q bitAnd: 1) isZero not & (r isZero)
will be handled by Integer>>asFloat"
((q bitAnd: 1) isZero or: [r isZero])
ifFalse: [q := q + 1].

^ (self positive
ifTrue: [q asFloat]
+ 		ifFalse: [q = 0
+ 			ifTrue: [Float negativeZero]
+ 			ifFalse: [q asFloat negated]])
- 		ifFalse: [q asFloat negated])
timesTwoPower: exponent!

```