Integer.st
changeset 18851 11fd28f8c61e
parent 18769 200092d3b654
child 18858 2968df243134
child 18865 1e6e937f7cf0
--- a/Integer.st	Tue Oct 27 19:30:26 2015 +0100
+++ b/Integer.st	Tue Oct 27 19:34:24 2015 +0100
@@ -763,8 +763,6 @@
     "Modified: / 15.11.1999 / 20:35:20 / cg"
 ! !
 
-
-
 !Integer class methodsFor:'class initialization'!
 
 initialize
@@ -825,7 +823,6 @@
     "
 ! !
 
-
 !Integer class methodsFor:'prime numbers'!
 
 flushPrimeCache
@@ -1148,7 +1145,6 @@
     ^ self == Integer
 ! !
 
-
 !Integer methodsFor:'*Roe'!
 
 acceptRoeVisitor: aVisitor
@@ -1417,7 +1413,6 @@
     "
 ! !
 
-
 !Integer methodsFor:'bcd conversion'!
 
 decodeFromBCD
@@ -2289,22 +2284,17 @@
 digitByteLength
     "return the number bytes required for a 2's complement
      binary representation of this Integer.
-     For positive receivers, thats the same as the digitLength."
-
-    "
-     check if there is a 0-byte ...
-     this allows to ask unnormalized LargeIntegers
-     for their digitLength
-    "
-    |l "{ Class: SmallInteger }" |
+     For positive receivers, that's the same as the digitLength."
+
+    |absLen "{ Class: SmallInteger }" |
 
     self >= 0 ifTrue:[^ self digitLength].
 
-    l := self negated digitLength.
-    (self digitByteAt:l) == 16rFF ifTrue:[
-        ^ (l - 1) max:1
+    absLen := self negated digitLength.
+    (self digitByteAt:absLen) == 16rFF ifTrue:[
+        ^ (absLen - 1) max:1
     ].
-    ^ l
+    ^ absLen
 
     "
      -129 digitByteLength
@@ -2315,7 +2305,7 @@
 !
 
 digitBytes
-    "return a byteArray filled with the receivers bits
+    "return a byteArray filled with the receiver's bits
      (8 bits of the absolute value per element),
      least significant byte is first"
 
@@ -2323,7 +2313,7 @@
 !
 
 digitBytesMSB
-    "return a byteArray filled with the receivers bits
+    "return a byteArray filled with the receiver's bits
      (8 bits of the absolute value per element),
      most significant byte is first"
 
@@ -2331,7 +2321,7 @@
 !
 
 digitBytesMSB:msbFlag
-    "return a byteArray filled with the receivers bits
+    "return a byteArray filled with the receiver's bits
      (8 bits of the absolute value per element),
      if msbflag = true, most significant byte is first,
      otherwise least significant byte is first"
@@ -2688,7 +2678,7 @@
 
 acker:n
     "return the value of acker(self, n).
-      ;-) Do not try with receivers > 3"
+     ;-) Do not try with receivers > 3"
 
     (self == 0) ifTrue:[^ n + 1].
     (n == 0) ifTrue:[^ (self - 1) acker: 1].
@@ -3163,10 +3153,19 @@
     "newton's method to get 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
-     (ans also in cryptography)"
+     (and also in cryptography)"
 
     |guess prevGuess guessSquared|
 
+    self negative ifTrue:[
+        ^ self class
+            raise:#imaginaryResultSignal
+            receiver:self
+            selector:#integerSqrt
+            arguments:#()
+            errorString:'bad (negative) receiver in sqrt'
+    ].
+    
     guess := (1 bitShift:(self highBit // 2)).
 
     [ 
@@ -3184,7 +3183,6 @@
 
     ^ guess.
 
-
     "
      333 integerSqrt          
      325 integerSqrt          
@@ -3192,7 +3190,10 @@
      323 integerSqrt          
      10239552311579 integerSqrt
      5397346292805549782720214077673687806275517530364350655459511599582614290 integerSqrt
-     1000 factorial integerSqrt 
+     1000 factorial integerSqrt
+     
+     1000 factorial - 1000 factorial integerSqrt squared
+     1000 factorial - (1000 factorial integerSqrt + 1) squared
    "
 !
 
@@ -3563,6 +3564,19 @@
 
     "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'!
@@ -3756,8 +3770,7 @@
 
     "
      claus: changed it from a recursive algorithm;
-     (it used to trigger stack-overflow exceptions when printing
-      3000 factorial ...)
+     (it used to trigger stack-overflow exceptions when printing 3000 factorial ...)
     "
 "/    leftPart := num // base.
 "/    (leftPart ~= 0) ifTrue:[
@@ -3774,20 +3787,24 @@
     "/ within that junk) and speeds up the conversions noticably.
 
     r2 := base*base.   "/ radix^2
-    r4 := r2*r2.             "/ radix^4
+    r4 := r2*r2.        "/ radix^4
     base <= 10 ifTrue:[
-        r := r4*r2.        "/ radix^6
+        r := r4*r2.     "/ radix^6 (chunks of 6 digits)
         nD := 6.
     ] ifFalse:[
-        r := r4*base.    "/ radix^5
+        r := r4*base.    "/ radix^5 (chunks of 5 digits)
         nD := 5.
     ].
-
+    SmallInteger maxBits >= 63 ifTrue:[
+        r := r*r.    "/ radix^10 / radix^12 (chunks of 10/12 digits)
+        nD := nD * 2.
+    ].
+   
     "get a Stream with space for the digits we are going to print.
      We need ((num log:base) ceiling) digits, which is equivalent
      to ((num log:2)/(base log:2) ceiling)
     "
-    s := WriteStream on:(String new:((num highBit // base highBit - 1) + 1)).
+    s := WriteStream on:(String new:10).
 
     [num >= r] whileTrue:[
         "/
@@ -3819,9 +3836,11 @@
         3000 factorial printOn:Transcript base:10
         10 printOn:Transcript base:3
         31 printOn:Transcript base:3
+        10 printOn:Transcript base:2
+        31 printOn:Transcript base:2
         -20  printOn:Transcript base:16
         -20  printOn:Transcript base:10
-        Time millisecondsToRun:[10000 factorial printString]   7650
+        Time millisecondsToRun:[10000 factorial printString] 610  7650
     "
 
     "Modified: / 20-01-1998 / 18:05:02 / stefan"
@@ -4393,7 +4412,6 @@
     "Created: / 09-01-2012 / 17:18:06 / cg"
 ! !
 
-
 !Integer methodsFor:'special modulo arithmetic'!
 
 add_32:anInteger
@@ -4909,7 +4927,7 @@
 
 integerPart
     "return a number with value from digits before the decimal point.
-     (i.e. the receivers truncated value)
+     (i.e. the receiver's truncated value)
      Since integers have no fraction, return the receiver here."
 
     ^ self