[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