Integer.st
changeset 18865 1e6e937f7cf0
parent 18851 11fd28f8c61e
child 18873 ce58d469e583
child 18905 256565ff9803
--- a/Integer.st	Wed Oct 28 09:16:52 2015 +0100
+++ b/Integer.st	Wed Oct 28 09:19:04 2015 +0100
@@ -17,7 +17,7 @@
 
 Number subclass:#Integer
 	instanceVariableNames:''
-	classVariableNames:'DefaultDisplayRadix BCDConversionErrorSignal PrimeCache'
+	classVariableNames:'BCDConversionErrorSignal PrimeCache'
 	poolDictionaries:''
 	category:'Magnitude-Numbers'
 !
@@ -56,16 +56,6 @@
         int op fraction    -> fraction
         int op float       -> float
 
-    [Class variables:]
-
-        DefaultDisplayRadix     the radix in which integers present their
-                                displayString (which is used in inspectors)
-                                If you are to look at many hex numbers, bitmasks
-                                etc. you may set this to 2 or 16.
-                                (avoids typing printStringRadix:.. all the time
-                                 - I know - I am lazy ;-). Default is 10.
-
-
     [author:]
         Claus Gittinger
 
@@ -808,25 +798,11 @@
     "Modified: 18.7.1996 / 12:26:38 / cg"
 ! !
 
-!Integer class methodsFor:'misc'!
-
-displayRadix:aNumber
-    "being tired of always sending #printStringRadix: in the inspectors,
-     this allows you to change the default print radix for the displayString
-     method."
-
-    DefaultDisplayRadix := aNumber
-
-    "
-     Integer displayRadix:16. 123456 inspect
-     Integer displayRadix:10. 123456 inspect
-    "
-! !
-
 !Integer class methodsFor:'prime numbers'!
 
 flushPrimeCache
-    "cleanup after using a primeCache"
+    "cleanup after using a primeCache.
+     See comment in initializePrimeCacheUpTo:limit"
 
     PrimeCache := nil.
 
@@ -950,6 +926,8 @@
 !
 
 primeCacheSize
+    "see comment in initializePrimeCacheUpTo:limit"
+    
     ^ PrimeCache size * 2
 
     "
@@ -1078,8 +1056,9 @@
 !
 
 primesUpTo: max do: aBlock
-    "Compute aBlock with all prime integers up to and including the given integer."
-
+    "Compute aBlock with all prime integers up to and including the given integer.
+     See comment in initializePrimeCacheUpTo:limit"
+     
     | limit flags prime k |
 
     max <= 2000 ifTrue:[
@@ -3150,10 +3129,10 @@
 !
 
 integerSqrt
-    "newton's method to get the largest integer which is less or equal to the
+    "return the largest integer which is less or equal to the
      receiver's square root. 
      This might be needed for some number theoretic problems with large numbers
-     (and also in cryptography)"
+     (and also in cryptography). Uses Newton's method"
 
     |guess prevGuess guessSquared|
 
@@ -3302,6 +3281,8 @@
 
      (*):which does not mean that the code below is optimal - far from it !!"
 
+    "See comment in initializePrimeCacheUpTo:limit"
+
     |rest n factors limit lastPrime checkThisFactor nextTry|
 
     factors := Bag new.
@@ -3564,19 +3545,6 @@
 
     "Created: / 30.4.1999 / 15:53:15 / stefan"
     "Modified: / 5.5.1999 / 11:01:15 / stefan"
-!
-
-raisedToInteger:exp
-    "return the receiver raised to exp"
-
-    exp > 1000 ifTrue:[
-        "LargeInteger req's more than 1000 bits"    
-        (self < 0) ifTrue:[
-            ^ PowerInteger new base:(self negated) exponent:exp negative:(exp odd).
-        ].    
-        ^ PowerInteger new base:self exponent:exp
-    ].
-    ^ self raisedToIntegerAsInteger:exp
 ! !
 
 !Integer methodsFor:'printing & storing'!
@@ -3652,30 +3620,6 @@
     "
 !
 
-displayOn:aGCOrStream
-    "return a string to display the receiver.
-     The output radix is usually 10, but can be changed by setting
-     DefaultDisplayRadix (see Integer>>displayRadix:)"
-
-    "/ what a kludge - Dolphin and Squeak mean: printOn: a stream;
-    "/ ST/X (and some old ST80's) mean: draw-yourself on a GC.
-    (aGCOrStream isStream) ifFalse:[
-        ^ super displayOn:aGCOrStream
-    ].
-
-    (DefaultDisplayRadix isNil or:[DefaultDisplayRadix == 10]) ifTrue:[
-        self printOn:aGCOrStream
-    ] ifFalse:[
-        self printOn:aGCOrStream base:DefaultDisplayRadix showRadix:true.
-    ].
-
-    "
-     Integer displayRadix:16. 12345
-     Integer displayRadix:2.  12345
-     Integer displayRadix:10. 12345
-    "
-!
-
 errorPrintHex
     "print the receiver as a hex number on the standard error stream"
 
@@ -3716,32 +3660,6 @@
      (self printStringRadix:16) print
 !
 
-printOn:aStream
-    "append a printed description of the receiver to aStream"
-
-    self printOn:aStream base:10
-
-    "Modified: / 20.1.1998 / 14:10:45 / stefan"
-!
-
-printOn:aStream base:b
-    "return a string representation of the receiver in the specified
-     radix (without the initial XXr)"
-
-    ^ self printOn:aStream base:b showRadix:false
-
-    "
-     10 printOn:Transcript base:3
-     31 printOn:Transcript base:3
-     -20 printOn:Transcript base:16
-     -20 printOn:Transcript base:10
-     3000 factorial printOn:Transcript base:10
-    "
-
-    "Modified: / 20.1.1998 / 18:05:02 / stefan"
-    "Modified: / 7.9.2001 / 13:52:17 / cg"
-!
-
 printOn:aStream base:b showRadix:showRadix
     "append a string representation of the receiver in the specified numberBase to aStream
      (if showRadix is true, with initial XXr)
@@ -3772,13 +3690,13 @@
      claus: changed it from a recursive algorithm;
      (it used to trigger stack-overflow exceptions when printing 3000 factorial ...)
     "
-"/    leftPart := num // base.
-"/    (leftPart ~= 0) ifTrue:[
-"/        leftPart printOn:aStream base:base.
-"/        aStream nextPut:(Character digitValue:(num \\ base).
-"/        ^ self
-"/    ].
-"/    aStream nextPut:(Character digitValue:num).
+    "/    leftPart := num // base.
+    "/    (leftPart ~= 0) ifTrue:[
+    "/        leftPart printOn:aStream base:base.
+    "/        aStream nextPut:(Character digitValue:(num \\ base).
+    "/        ^ self
+    "/    ].
+    "/    aStream nextPut:(Character digitValue:num).
 
     "/ instead of computing the quotient and remainder
     "/ against radix, do it in junks of 5 or 6 digits.
@@ -4019,21 +3937,6 @@
     "Modified (comment): / 26-07-2013 / 12:55:18 / cg"
 !
 
-printStringRadix:base showRadix:showRadixBoolean
-    "return a string representation of the receiver in the specified
-     base; does NOT prepend XXr to the string.
-     See also: radixPrintStringRadix:
-               printOn:base:showRadix:"
-
-    |s|
-
-    s := WriteStream on:(String basicNew:20).
-    self printOn:s base:base showRadix:showRadixBoolean.
-    ^ s contents
-
-    "Created: / 23-09-2011 / 13:59:19 / cg"
-!
-
 printStringRadix:aRadix size:sz fill:fillCharacter
     "return a string representation of the receiver in the specified
      radix. The string is padded on the left with fillCharacter to make
@@ -4055,25 +3958,6 @@
     "
 !
 
-radixPrintStringRadix:radix
-    "return a string representation of the receiver in the specified
-     base; prepend XXr to the string"
-
-    ^ self printStringRadix:radix showRadix:true
-
-    "
-     31 radixPrintStringRadix:2
-     31 radixPrintStringRadix:3
-     31 radixPrintStringRadix:10
-     31 radixPrintStringRadix:16
-     31 radixPrintStringRadix:36
-    "
-
-    "Created: / 19-01-1998 / 17:38:00 / stefan"
-    "Modified: / 20-01-1998 / 14:11:03 / stefan"
-    "Modified: / 23-09-2011 / 14:00:02 / cg"
-!
-
 romanPrintString
     "return a roman number representation of the receiver as a string"
 
@@ -4177,6 +4061,54 @@
     ^ true
 !
 
+isPerfectSquare
+    "return true if I am a perfect square.
+     That is a number for which the square root is an integer."
+     
+    |intSqrt realSqrt|
+    
+    self strictlyPositive ifFalse:[
+        "/ should we raise a domain error for negative receivers?
+        ^ false
+    ].
+
+    "/ q&d check for common small squares
+    self < 400 ifTrue:[    
+        ^ #(1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 ) includes:self.
+    ].        
+    self < 1024 ifTrue:[    
+        ^ #(400 441 484 529 576 625 676 729 784 841 900 961) includes:self.
+    ].        
+    "/ try powers of 2
+    self isPowerOfTwo ifTrue:[
+        ^ self lowBit odd
+    ].
+    
+    "/ guess
+    realSqrt := self sqrt.
+    realSqrt isFinite ifTrue:[
+        realSqrt = realSqrt truncated ifTrue:[
+            "/ still have to check due to rounding errors.
+            intSqrt := realSqrt truncated asInteger.
+            ^ intSqrt squared = self
+        ].    
+    ].
+    
+    "/ slow code
+    intSqrt := self integerSqrt.
+    ^ intSqrt squared = self
+
+    "
+     (1 to:1000000) count:[:n | n isPerfectSquare] 1000
+     12345678987654321234567 isPerfectSquare
+     123123123432 squared isPerfectSquare
+     (123123123432 raisedTo:7) isPerfectSquare
+     ((123456789123456789 raisedTo:7)) isPerfectSquare
+     ((123456789123456789 raisedTo:7)-1) isPerfectSquare
+     Time microsecondsToRun:[12345678987654321234567 isPerfectSquare]
+    "
+!
+
 isPowerOf:p
     "return true, if the receiver is a power of p"
 
@@ -4259,6 +4191,14 @@
     self even ifTrue:[^ self == 2 ].
     self == 1 ifTrue:[^ false ].
 
+    "/ See comment in initializePrimeCacheUpTo:limit
+    "/      Integer initializePrimeCacheUpTo:(10 raisedTo:7)
+    "/      Integer flushPrimeCache
+    "/
+    "/ by default, no primeCache is used.
+    "/ if you do lots of number-stuff with primes, you may want to enable it with
+    "/      Integer initializePrimeCacheUpTo:1000000
+    "/ and when done, cleanup with flushPrimeCache
     self <= (PrimeCache size*2) ifTrue:[
         ^ PrimeCache at:self//2.
     ].
@@ -4369,6 +4309,7 @@
      37 nextPrime
      36 nextPrime
      3456737 nextPrime
+     1000 factorial nextPrime
     "
 !