[Pkg] The Trunk: Kernel-nice.641.mcz
commits at source.squeak.org
commits at source.squeak.org
Wed Oct 19 18:45:11 UTC 2011
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.641.mcz
==================== Summary ====================
Name: Kernel-nice.641
Author: nice
Time: 19 October 2011, 8:44:12.297 pm
UUID: e31730ef-2db4-42e3-aa0e-299e45c955ac
Ancestors: Kernel-nice.640
Correct #nthRootTruncated: (it did call #nthRootFloor:)
Let #nthRoot: retry in exact arithmetic if ever Float overflows.
=============== Diff against Kernel-nice.640 ===============
Item was changed:
----- Method: Integer>>nthRoot: (in category 'mathematical functions') -----
nthRoot: aPositiveInteger
"Answer the nth root of the receiver."
| selfAsFloat floatResult guess raised higher lower delta |
selfAsFloat := self asFloat.
floatResult := selfAsFloat nthRoot: aPositiveInteger.
+ "If we can't do Float arithmetic, then look for an exact answer in exact arithmetic"
- "If we can't do Float arithmetic, currently we can't look for an exact answer"
floatResult isInfinite ifTrue: [
+ guess := self nthRootTruncated: aPositiveInteger.
+ (guess raisedToInteger: aPositiveInteger) = self ifTrue: [^guess].
^floatResult ].
guess := floatResult rounded.
"If got an exact answer, answer it."
raised := guess raisedToInteger: aPositiveInteger.
raised = self
ifTrue: [ ^ guess ].
"In this case, maybe it failed because we are such a big integer that the Float
method gets inexact, even if we are a whole square number.
Note (jmv): The algorithms I found for computing the nthRoot would havily use
very large fractions. I wrote this one, that doesn't create fractions."
selfAsFloat abs >= (Float maxExactInteger asFloat raisedToInteger: aPositiveInteger)
ifTrue: [
raised > self
ifTrue: [
higher := guess.
delta := floatResult predecessor - floatResult.
[
floatResult := floatResult + delta.
lower := floatResult rounded.
(lower raisedToInteger: aPositiveInteger) > self ] whileTrue: [
delta := delta * 2.
higher := lower ] ]
ifFalse: [
lower := guess.
delta := floatResult successor - floatResult.
[
floatResult := floatResult + delta.
higher := floatResult rounded.
(higher raisedToInteger: aPositiveInteger) < self ] whileTrue: [
delta := delta * 2.
lower := higher ]].
[ higher - lower > 1 ] whileTrue: [
guess := lower + higher // 2.
raised := guess raisedToInteger: aPositiveInteger.
raised = self
ifTrue: [
^ guess ].
raised > self
ifTrue: [ higher := guess ]
ifFalse: [ lower := guess ]]].
"We need an approximate result"
^floatResult!
Item was changed:
----- Method: Integer>>nthRootTruncated: (in category 'mathematical functions') -----
nthRootTruncated: aPositiveInteger
"Answer the integer part of the nth root of the receiver."
| guess guessToTheNthMinusOne delta |
self = 0 ifTrue: [^0].
self negative
ifTrue:
[aPositiveInteger even ifTrue: [ ArithmeticError signal: 'Negative numbers don''t have even roots.' ].
+ ^(self negated nthRootTruncated: aPositiveInteger) negated].
- ^(self negated nthRootFloor: aPositiveInteger) negated].
guess := 1 bitShift: self highBitOfMagnitude + aPositiveInteger - 1 // aPositiveInteger.
[
guessToTheNthMinusOne := guess raisedTo: aPositiveInteger - 1.
delta := (guess * guessToTheNthMinusOne - self) // (guessToTheNthMinusOne * aPositiveInteger).
delta = 0 ] whileFalse:
[ guess := guess - delta ].
( (guess := guess - 1) raisedTo: aPositiveInteger) > self ifTrue:
[ guess := guess - 1 ].
^guess!
More information about the Packages
mailing list