[squeak-dev] 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 Squeak-dev mailing list