--- a/ArithmeticValue.st Fri Nov 12 12:35:54 2004 +0100
+++ b/ArithmeticValue.st Fri Nov 12 13:09:17 2004 +0100
@@ -969,9 +969,88 @@
!ArithmeticValue methodsFor:'mathematical functions'!
raisedTo: aNumber
+ aNumber isInteger ifTrue:[
+ ^ self raisedToInteger:aNumber
+ ].
^ self subclassResponsibility
!
+raisedToInteger:exp
+ "return the receiver raised to exp"
+
+ |result e t|
+
+ "use the addition chaining algorithm,
+ which is much faster for big exp-arguments"
+
+ result := 1.
+ t := self.
+ exp < 0 ifTrue:[
+ e := exp negated.
+ ] ifFalse:[
+ e := exp.
+ ].
+
+ [e ~~ 0] whileTrue:[
+ [(e bitAnd:1) == 0] whileTrue:[
+ e := e bitShift:-1.
+ t := t * t.
+ ].
+ e := e - 1.
+ result := result * t.
+ ].
+
+ (exp < 0) ifTrue:[
+ ^ 1 / result
+ ].
+
+ ^ result
+
+
+ "
+ (2 raisedToInteger:216)
+ (2 raisedTo:216)
+-> 105312291668557186697918027683670432318895095400549111254310977536
+
+ (2 raisedToInteger:216) asFloat
+ (2 raisedTo:216) asFloat
+-> 1.05312E+65
+
+ (2 raisedToInteger:500)
+ (2 raisedTo:500)
+-> 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589376
+ 2 raisedToInteger:10
+-> 1024
+ -2 raisedToInteger:10
+-> 1024
+ -2 raisedToInteger:9
+-> -512
+ 10 raisedToInteger:-10
+-> (1/10000000000)
+ 2 raisedToInteger:0
+-> 1
+ 2 raisedToInteger:-1
+-> (1/2)
+
+ Time millisecondsToRun:[
+ 10000 timesRepeat:[
+ (2 raisedToInteger:500)
+ ]
+ ]
+
+ Time millisecondsToRun:[
+ |bigNum|
+ bigNum := 2 raisedToInteger:500.
+ 10 timesRepeat:[
+ (bigNum raisedToInteger:500)
+ ]
+ ]
+ "
+
+ "Created: / 27.4.1999 / 15:19:22 / stefan"
+ "Modified: / 27.4.1999 / 16:16:11 / stefan"
+!
+
squared
"return receiver * receiver"
@@ -1164,7 +1243,7 @@
!ArithmeticValue class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/ArithmeticValue.st,v 1.66 2004-07-14 14:54:59 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ArithmeticValue.st,v 1.67 2004-11-12 12:09:17 cg Exp $'
! !
ArithmeticValue initialize!