Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.1270.mcz ==================== Summary ==================== Name: Kernel-nice.1270 Author: nice Time: 1 October 2019, 9:22:39.460936 pm UUID: 05ae7bbb-2517-4c6e-a9c0-db89b42742e5 Ancestors: Kernel-mt.1269 In SmallFloat64>>#truncated fallback, don't bother with Infinities and NaN, since all SmallFloat64 are finite, nor with Float fractionPart, since all non-integer Float value fits in SmallInteger in a 64bits image, and thus are already handled by the primitive. It's legitimate to inject such implementation specific knowledge into this implementation specific class. Also revise BoxedFloat64>>#truncated, mostly with comments. Dividing by SmallInteger maxVal + 1 / 2 would lead to an infinite loop in a 64bits image, fortunately this branch is unreachable then. Each time I read it, I have the shadow of a doubt ;) =============== Diff against Kernel-mt.1269 =============== Item was changed: ----- Method: BoxedFloat64>>truncated (in category 'truncation and round off') ----- truncated "Answer with a SmallInteger equal to the value of the receiver without its fractional part. The primitive fails if the truncated value cannot be represented as a SmallInteger. In that case, the code below will compute a LargeInteger truncated value. Essential. See Object documentation whatIsAPrimitive. " <primitive: 51> self isFinite ifFalse: [self error: 'Cannot truncate this number']. + self abs < 4.503599627370496e15 + "Float maxExactInteger/2 = (1.0 timesTwoPower: Float precision - 1)" + "Every Float bigger than or equal to that has ulp >= 1, thus no fractionPart" - - self abs < 2.0e16 ifTrue: ["Fastest way when it may not be an integer" + "This branch is unreachable in 64 bits image" | di df q r | di := 1 + (SmallInteger maxVal bitShift: -1). df := di asFloat. q := self quo: df. r := self - (q asFloat * df). ^q * di + r truncated] + ifFalse: [^ self asTrueFraction. "Extract all bits of the significand and shift if necessary"] - ifFalse: [^ self asTrueFraction. "Extract all bits of the mantissa and shift if necess"] ! Item was changed: ----- Method: SmallFloat64>>truncated (in category 'truncation and round off') ----- truncated "Answer with a SmallInteger equal to the value of the receiver without its fractional part. The primitive fails if the truncated value cannot be represented as a SmallInteger. In that case, the code below will compute a LargeInteger truncated value. Essential. See Object documentation whatIsAPrimitive. " <primitive: 551> + "Since SmallInteger maxVal highBit >= Float precision, in 64bits image/VM, + every Float with ulp < 1 - that is which may have a fractionPart - fits in a SmallInteger. + Thus only care of Float with ulp >= 1 which have Integer value." + ^ self asTrueFraction - self isFinite ifFalse: [self error: 'Cannot truncate this number']. - - self abs < 2.0e16 - ifTrue: ["Fastest way when it may not be an integer" - | di df q r | - di := 1 + (SmallInteger maxVal bitShift: -1). - df := di asFloat. - q := self quo: df. - r := self - (q asFloat * df). - ^q * di + r truncated] - ifFalse: [^ self asTrueFraction. "Extract all bits of the mantissa and shift if necess"] - ! |
Free forum by Nabble | Edit this page |