Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.1048.mcz ==================== Summary ==================== Name: Kernel-nice.1048 Author: nice Time: 30 October 2016, 5:18:07.732545 pm UUID: 476a34de-b988-44ea-8d97-3b553e3e879e Ancestors: Kernel-nice.1047 Move the duplicated fallback code for timesTwoPower: primitive up in Float. Adjust the limits a bit, - we can evaluate down to (1.0 timesTwoPower: -1074) with gradual underflow (Float emin - Float precision + 1). - we can shift by 29 with SmallInteger, so correctly set the limit to -30 < exponent < 30 =============== Diff against Kernel-nice.1047 =============== Item was changed: ----- Method: BoxedFloat64>>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> + ^super timesTwoPower: anInteger! - 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]]. - - ^ self * (2.0 raisedToInteger: anInteger)! Item was added: + ----- Method: Float>>timesTwoPower: (in category 'mathematical functions') ----- + timesTwoPower: anInteger + "Answer with the receiver multiplied by 2.0 raised + to the power of the argument" + + 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 - Float precision + 1) + ifTrue: + [| deltaToUnderflow | + deltaToUnderflow := Float emin - self exponent max: Float emin - Float precision + 1. + 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 > -30 ifTrue: [ + anInteger < 0 ifTrue: [^ self / (1 bitShift: 0 - anInteger) asFloat]. + anInteger < 30 ifTrue: [^ self * (1 bitShift: anInteger) asFloat]]. + + ^ self * (2.0 raisedToInteger: anInteger)! Item was changed: ----- Method: SmallFloat64>>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: 554> + ^super timesTwoPower: anInteger! - 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]]. - - ^ self * (2.0 raisedToInteger: anInteger)! |
Free forum by Nabble | Edit this page |