The Trunk: Kernel-nice.1270.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Kernel-nice.1270.mcz

commits-2
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"]
-
 
 
  !