[Pkg] The Trunk: Kernel-nice.1270.mcz
commits at source.squeak.org
commits at source.squeak.org
Tue Oct 1 19:22:49 UTC 2019
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"]
-
!
More information about the Packages
mailing list