[squeak-dev] The Trunk: Kernel-nice.853.mcz

commits at source.squeak.org commits at source.squeak.org
Wed May 21 00:54:20 UTC 2014


Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.853.mcz

==================== Summary ====================

Name: Kernel-nice.853
Author: nice
Time: 21 May 2014, 2:52:52.286 am
UUID: 0c682a44-c243-440b-8caf-399be09824bc
Ancestors: Kernel-eem.852

Introduce an isAnExactFloat test, which is true when a Number can be converted as Float exactly.
Use this to boost some mixed arithmetic comparisons by avoidance of Float>>asTrueFraction in more cases.
Use this to make Fraction>>hash more explicit.
While at it, improve a bit the Fraction>>hash in inexact case (previous naive bitXor: causes too many collisions)
Since some hash has been modified, rehashAll in postscript.

=============== Diff against Kernel-eem.852 ===============

Item was changed:
  ----- Method: Float>>adaptToFraction:andCompare: (in category 'converting') -----
  adaptToFraction: rcvr andCompare: selector 
  	"If I am involved in comparison with a Fraction, convert myself to a
  	Fraction. This way, no bit is lost and comparison is exact."
  	
  	self isFinite
  		ifFalse: [
  			selector == #= ifTrue: [^false].
  			selector == #~= ifTrue: [^true].
  			self isNaN ifTrue: [^ false].
  			(selector = #< or: [selector = #'<='])
  				ifTrue: [^ self positive].
  			(selector = #> or: [selector = #'>='])
  				ifTrue: [^ self positive not].
  			^self error: 'unknow comparison selector'].
  		
  	"Try to avoid asTrueFraction because it can cost"
+ 	rcvr isAnExactFloat ifTrue: [^rcvr asExactFloat perform: selector with: self].
+ 	selector == #= ifTrue: [^false].
+ 	selector == #~= ifTrue: [^true].
- 	selector == #= ifTrue: [
- 		rcvr denominator isPowerOfTwo ifFalse: [^false]].
- 	selector == #~= ifTrue: [
- 		rcvr denominator isPowerOfTwo ifFalse: [^true]].
- 
  	^ rcvr perform: selector with: self asTrueFraction!

Item was changed:
  ----- Method: Float>>adaptToInteger:andCompare: (in category 'converting') -----
  adaptToInteger: rcvr andCompare: selector 
  	"If I am involved in comparison with an Integer, convert myself to a
  	Fraction. This way, no bit is lost and comparison is exact."
  	
  	self isFinite
  		ifFalse: [
  			selector == #= ifTrue: [^false].
  			selector == #~= ifTrue: [^true].
  			self isNaN ifTrue: [^ false].
  			(selector = #< or: [selector = #'<='])
  				ifTrue: [^ self positive].
  			(selector = #> or: [selector = #'>='])
  				ifTrue: [^ self positive not].
  			^self error: 'unknow comparison selector'].
  		
  	"Try to avoid asTrueFraction because it can cost"
  	selector == #= ifTrue: [
  		self fractionPart = 0.0 ifFalse: [^false]].
  	selector == #~= ifTrue: [
  		self fractionPart = 0.0 ifFalse: [^true]].
  	
+ 	rcvr isAnExactFloat ifTrue: [^rcvr asExactFloat perform: selector with: self].
+ 	selector == #= ifTrue: [^false].
+ 	selector == #~= ifTrue: [^true].
  	^ rcvr perform: selector with: self asTrueFraction!

Item was changed:
  ----- Method: Float>>adaptToScaledDecimal:andCompare: (in category 'converting') -----
  adaptToScaledDecimal: rcvr andCompare: selector 
  	"If I am involved in comparison with a scaled Decimal, convert myself to a
  	Fraction. This way, no bit is lost and comparison is exact."
  	
  	self isFinite
  		ifFalse: [
  			selector == #= ifTrue: [^false].
  			selector == #~= ifTrue: [^true].
  			self isNaN ifTrue: [^ false].
  			(selector = #< or: [selector = #'<='])
  				ifTrue: [^ self positive].
  			(selector = #> or: [selector = #'>='])
  				ifTrue: [^ self positive not].
  			^self error: 'unknow comparison selector'].
  
+ 	"Try to avoid asTrueFraction because it can cost"
+ 	rcvr isAnExactFloat ifTrue: [^rcvr asExactFloat perform: selector with: self].
+ 	selector == #= ifTrue: [^false].
+ 	selector == #~= ifTrue: [^true].
  	^ rcvr perform: selector with: self asTrueFraction!

Item was added:
+ ----- Method: Float>>isAnExactFloat (in category 'testing') -----
+ isAnExactFloat
+ 	^true!

Item was added:
+ ----- Method: Fraction>>asExactFloat (in category 'converting') -----
+ asExactFloat
+ 	"When we know that this Fraction is an exact Float, this conversion is much faster than asFloat."
+ 
+ 	^numerator asFloat timesTwoPower: 1 - denominator highBit!

Item was changed:
  ----- Method: Fraction>>hash (in category 'comparing') -----
  hash
+ 	"Hash is reimplemented because = is implemented."
- 	"Hash is reimplemented because = is implemented.
- 	Care is taken that a Fraction equal to a Float also have an equal hash"
- 
- 	| tmp |
- 	denominator isPowerOfTwo ifTrue: [
- 		"If denominator is a power of two, I can be exactly equal to a Float"
- 		tmp := self asFloat.
- 		tmp isFinite ifTrue: [^tmp hash]].
  	
+ 	"Care is taken that a Fraction equal to a Float also has an equal hash"
+ 	self isAnExactFloat ifTrue: [^self asExactFloat hash].
+ 	
+ 	"Else, I cannot be exactly equal to a Float, use own hash algorithm."
+ 	^numerator hash hashMultiply bitXor: denominator hash!
- 	"Else, I cannot be exactly equal to a Float, use own hash algorithm.
- 	(Assume the fraction is already reduced)"
- 	^numerator hash bitXor: denominator hash!

Item was added:
+ ----- Method: Fraction>>isAnExactFloat (in category 'testing') -----
+ isAnExactFloat
+ 	"Answer true if this Fraction can be converted exactly to a Float"
+ 	^ denominator isPowerOfTwo
+ 		and: ["I have a reasonable significand: not too big"
+ 			numerator highBitOfMagnitude <= Float precision
+ 				and: ["I have a reasonable exponent: not too small"
+ 					Float emin + denominator highBitOfMagnitude <= Float precision]]!

Item was added:
+ ----- Method: Integer>>isAnExactFloat (in category 'testing') -----
+ isAnExactFloat
+ 	"Answer true if this Integer can be converted exactly to a Float"
+ 	| h |
+ 	(h := self highBitOfMagnitude) <= Float precision
+ 		ifTrue: [^ true].
+ 	^ h - 1 <= Float emax
+ 		and: [h - self abs lowBit < Float precision]!

Item was changed:
  ----- Method: Number>>adaptToFloat:andCompare: (in category 'converting') -----
  adaptToFloat: rcvr andCompare: selector 
  	"If I am involved in comparison with a Float, convert rcvr to a
  	Fraction. This way, no bit is lost and comparison is exact."
  	
  	rcvr isFinite
  		ifFalse: [
  			selector == #= ifTrue: [^false].
  			selector == #~= ifTrue: [^true].
  			rcvr isNaN ifTrue: [^ false].
  			(selector = #< or: [selector = #'<='])
  				ifTrue: [^ rcvr positive not].
  			(selector = #> or: [selector = #'>='])
  				ifTrue: [^ rcvr positive].
  			^self error: 'unknow comparison selector'].
  
+ 	"Try to avoid asTrueFraction because it can cost"
+ 	self isAnExactFloat ifTrue: [^rcvr perform: selector with: self asExactFloat].
+ 	selector == #= ifTrue: [^false].
+ 	selector == #~= ifTrue: [^true].
  	^ rcvr asTrueFraction perform: selector with: self!

Item was added:
+ ----- Method: Number>>asExactFloat (in category 'converting') -----
+ asExactFloat
+ 	"Convert this number asFloat with a priori knowledge that it is an exact Float.
+ 	Some subclass might exploit this knowledge for a faster implementation.
+ 	Only send this if self isAnExactFloat."
+ 	^self asFloat!

Item was added:
+ ----- Method: Number>>isAnExactFloat (in category 'testing') -----
+ isAnExactFloat
+ 	"Answer true if this Number can be converted exactly to a Float"
+ 	^self subclassResponsibility!

Item was added:
+ ----- Method: ScaledDecimal>>asExactFloat (in category 'converting') -----
+ asExactFloat
+ 	^fraction asExactFloat!

Item was added:
+ ----- Method: ScaledDecimal>>isAnExactFloat (in category 'testing') -----
+ isAnExactFloat
+ 	^fraction isAnExactFloat!

Item was changed:
+ (PackageInfo named: 'Kernel') postscript: 'HashedCollection rehashAll.'!
- (PackageInfo named: 'Kernel') postscript: 'Deprecation showDeprecationWarnings: Preferences showDeprecationWarnings.
- Preferences removePreference: #showDeprecationWarnings.'!



More information about the Squeak-dev mailing list