[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
|