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.'! |
Free forum by Nabble | Edit this page |