isPowerOfTwo tuned for large integers
authorClaus Gittinger <cg@exept.de>
Mon, 20 Jun 2011 12:43:28 +0200
changeset 13387 a50c610e265a
parent 13386 6986799e2da1
child 13388 0f3e6f1340c8
isPowerOfTwo tuned for large integers
Integer.st
--- a/Integer.st	Mon Jun 20 12:41:39 2011 +0200
+++ b/Integer.st	Mon Jun 20 12:43:28 2011 +0200
@@ -1139,7 +1139,6 @@
     ^ self == Integer
 ! !
 
-
 !Integer methodsFor:'Compatibility-Dolphin'!
 
 & aNumber
@@ -3918,30 +3917,8 @@
      100000 isPowerOf:10
      100001 isPowerOf:10
  "
-!
-
-isPowerOfTwo
-    "return true, if the receiver is a power of 2"
-
-"/ mhmh: how about the following
-"/    self == 0 ifTrue:[^ false].
-
-    ^ (self bitAnd:(self - 1)) == 0
-
-    "
-     0 isPowerOfTwo
-     1 isPowerOfTwo
-     2 isPowerOfTwo
-     3 isPowerOfTwo
-     4 isPowerOfTwo
-     16r8000000000000000 isPowerOfTwo
-     16r8000000000000001 isPowerOfTwo
-    "
-
-    "Modified: 15.10.1997 / 18:43:49 / cg"
 ! !
 
-
 !Integer methodsFor:'special access'!
 
 exponent
@@ -4387,6 +4364,32 @@
     ^ true
 !
 
+isPowerOfTwo
+    "return true, if the receiver is a power of 2"
+
+    "redefined, because the hacker's algorithm in smallInt is much slower for large numbers"
+
+    |maxBytes "{ Class: SmallInteger }"|
+
+    maxBytes := self digitLength.
+    (self digitAt:maxBytes) isPowerOfTwo ifFalse:[^ false].
+    1 to:maxBytes-1 do:[:byteIndex |
+        (self digitAt:byteIndex) ~~ 0 ifTrue:[^ false].
+    ].
+    ^ true
+
+    "
+     10000 factorial isPowerOfTwo  
+     |n| n := 10000 factorial. Time millisecondsToRun:[1000 timesRepeat:[ n isPowerOfTwo]] 
+    "
+    "
+     (2 raisedTo:10000) isPowerOfTwo  
+     |n| n := (2 raisedTo:10000). Time millisecondsToRun:[1000 timesRepeat:[ n isPowerOfTwo]] 
+    "
+
+    "Modified: / 20-06-2011 / 12:43:05 / cg"
+!
+
 isPrime
     "return true if I am a prime Number.
      This is a q&d hack, which may need optimization if heavily used."
@@ -4720,11 +4723,11 @@
 !Integer class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Integer.st,v 1.252 2011-05-13 13:58:36 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Integer.st,v 1.253 2011-06-20 10:43:28 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/Integer.st,v 1.252 2011-05-13 13:58:36 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Integer.st,v 1.253 2011-06-20 10:43:28 cg Exp $'
 ! !
 
 Integer initialize!