--- 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
"
!