[squeak-dev] The Trunk: Kernel-nice.1111.mcz
Chris Cunningham
cunningham.cb at gmail.com
Tue Aug 15 03:59:34 UTC 2017
I would just like to say that I really enjoy reading your math related
changes. I usually learn something new - but always get a enjoy the
opportunity to think about these things in a different light.
Thanks,
cbc
On Aug 13, 2017 3:03 PM, <commits at source.squeak.org> wrote:
> Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
> http://source.squeak.org/trunk/Kernel-nice.1111.mcz
>
> ==================== Summary ====================
>
> Name: Kernel-nice.1111
> Author: nice
> Time: 14 August 2017, 12:02:46.695166 am
> UUID: 280f8152-036b-48e1-b3f3-038fa2611ea7
> Ancestors: Kernel-tpr.1110
>
> Avoid costly and useless LargeInteger arithmetics when evaluating:
> (2009/2000) raisedTo: (3958333/100000)
>
> These large integer operations were helping to find the nearest Float
> approximation to the #nthRoot: but
> 1) they do not scale when the radical increases,
> 2) we then spoil the accuracy by raising the root to an Integer power
> naively and inacurately.
>
> Instead, if the result is inexact, fall back to a ln/exp formulation which
> is a few ulp off but at least fast.
>
> =============== Diff against Kernel-tpr.1110 ===============
>
> Item was changed:
> ----- Method: Fraction>>nthRoot: (in category 'mathematical functions')
> -----
> nthRoot: aPositiveInteger
> "Answer the nth root of the receiver."
>
> + | guess |
> + guess := (numerator nthRootTruncated: aPositiveInteger) /
> (denominator nthRootTruncated: aPositiveInteger).
> + (guess raisedTo: aPositiveInteger) = self ifTrue: [^guess].
> + "There is no exact nth root, so answer a Float approximation"
> + ^(self abs ln / aPositiveInteger) exp * self sign!
> - | d n |
> - n := numerator nthRoot: aPositiveInteger.
> - d := denominator nthRoot: aPositiveInteger.
> - "The #sqrt method in integer will only answer a Float if there's
> no exact square root.
> - So, we need a float anyway."
> - (n isInfinite or: [ d isInfinite ]) ifTrue: [
> - ^self asFloat nthRoot: aPositiveInteger ].
> - ^n / d!
>
> Item was added:
> + ----- Method: Fraction>>raisedToFraction: (in category 'mathematical
> functions') -----
> + raisedToFraction: aFraction
> + | root |
> + root := (self numerator nthRootTruncated: aFraction denominator) /
> (self denominator nthRootTruncated: aFraction denominator).
> + (root raisedToInteger: aFraction denominator) = self ifTrue:
> [^root raisedToInteger: aFraction numerator].
> + ^super raisedToFraction: aFraction!
>
> Item was added:
> + ----- Method: Integer>>raisedToFraction: (in category 'mathematical
> functions') -----
> + raisedToFraction: aFraction
> + | root |
> + root := self nthRootTruncated: aFraction denominator.
> + (root raisedToInteger: aFraction denominator) = self ifTrue:
> [^root raisedToInteger: aFraction numerator].
> + ^super raisedToFraction: aFraction!
>
> Item was changed:
> ----- Method: Number>>raisedTo: (in category 'mathematical functions')
> -----
> raisedTo: aNumber
> "Answer the receiver raised to aNumber."
>
> aNumber isInteger ifTrue: [
> "Do the special case of integer power"
> ^ self raisedToInteger: aNumber].
> aNumber isFraction ifTrue: [
> "Special case for fraction power"
> + ^ self raisedToFraction: aNumber].
> - ^ (self nthRoot: aNumber denominator) raisedToInteger:
> aNumber numerator ].
> self negative ifTrue: [
> ^ ArithmeticError signal: 'Negative numbers can''t be
> raised to float powers.' ].
> aNumber isZero ifTrue: [^ self class one]. "Special case of
> exponent=0"
> 1 = aNumber ifTrue: [^ self]. "Special case of exponent=1"
> self isZero ifTrue: [ "Special case of
> self = 0"
> aNumber negative
> ifTrue: [^ (ZeroDivide dividend: 1) signal]
> ifFalse: [^ self]].
> ^ (aNumber * self ln) exp "Otherwise use logarithms"!
>
> Item was added:
> + ----- Method: Number>>raisedToFraction: (in category 'mathematical
> functions') -----
> + raisedToFraction: aFraction
> + self isZero
> + ifTrue:
> + [aFraction negative ifTrue: [^ (ZeroDivide
> dividend: 1) signal].
> + ^self].
> + self negative ifFalse: [^(self ln * aFraction) exp].
> + aFraction denominator even
> + ifTrue: [^ ArithmeticError signal: 'nth root only defined
> for positive Integer n.'].
> + ^(self negated ln * aFraction) exp negated!
>
> Item was added:
> + ----- Method: ScaledDecimal>>raisedToFraction: (in category
> 'mathematical functions') -----
> + raisedToFraction: aFraction
> + | result |
> + result := self asFraction raisedToFraction: aFraction.
> + ^result isFloat
> + ifTrue: [result]
> + ifFalse: [result asScaledDecimal: scale]!
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20170814/1540ea58/attachment.html>
More information about the Squeak-dev
mailing list
|