Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.900.mcz==================== Summary ====================
Name: Kernel-nice.900
Author: nice
Time: 12 February 2015, 3:02:47.866 am
UUID: 3366e84f-225d-4519-b571-b099acdaba70
Ancestors: Kernel-bf.899
Rescue #timesTwoPower: fallback code from freshly discovered flaws.
Don't be sparing of comments, if we ever need some, that gonna be here
Some of us try very hard to make the tests speak in place of comments, I feel that having both don't hurt.
=============== Diff against Kernel-bf.899 ===============
Item was changed:
----- Method: Float>>timesTwoPower: (in category 'mathematical functions') -----
timesTwoPower: anInteger
"Primitive. Answer with the receiver multiplied by 2.0 raised
to the power of the argument.
Optional. See Object documentation whatIsAPrimitive."
<primitive: 54>
+ self isFinite ifFalse: [^self].
+ self isZero ifTrue: [^self].
+
+ "Make sure that (2.0 raisedTo: Integer) can be safely used without overflow
+ For example:
+ Float fminNormalized * (2.0 raisedTo: 2000) = Float infinity.
+ while:
+ (Float fminNormalized timesTwoPower: 2000) = (2.0 raisedTo: 2000+Float emin)."
+ anInteger > Float emax ifTrue: [^(self timesTwoPower: Float emax) timesTwoPower: anInteger - Float emax].
+
+ "In case of gradual underflow, timesTwoPower: is not exact, so greatest care must be taken
+ because two consecutive timesTwoPower: might differ from a single one"
+ anInteger < Float emin
+ ifTrue:
+ [| deltaToUnderflow |
+ deltaToUnderflow := Float emin - self exponent max: Float emin.
+ deltaToUnderflow >= 0 ifTrue:
+ ["self is already near or past underflow, so don't care, result will be zero"
+ deltaToUnderflow := Float emin].
+ ^(self timesTwoPower: deltaToUnderflow) timesTwoPower: anInteger - deltaToUnderflow].
+
+ "If (2.0 raisedToInteger: anInteger) fit in a positive SmallInteger, then use faster SmallInteger conversion.
+ Note that SmallInteger maxVal highBit = 30 in a 32 bits image, so 1 can be shifted 29 times."
+ anInteger > -29 ifTrue: [
+ anInteger < 0 ifTrue: [^ self / (1 bitShift: (0 - anInteger)) asFloat].
+ anInteger < 30 ifTrue: [^ self * (1 bitShift: anInteger) asFloat]].
+
-
- anInteger < -29 ifTrue: [^ self * (2.0 raisedToInteger: anInteger)].
- anInteger < 0 ifTrue: [^ self / (1 bitShift: (0 - anInteger)) asFloat].
- anInteger < 30 ifTrue: [^ self * (1 bitShift: anInteger) asFloat].
^ self * (2.0 raisedToInteger: anInteger)!