LargeInteger.st
branchjv
changeset 17754 5322906cdb6a
parent 17735 6a5bc05f696a
child 17761 b0e5971141bc
--- a/LargeInteger.st	Thu Feb 25 22:58:21 2010 +0000
+++ b/LargeInteger.st	Mon Mar 08 21:39:02 2010 +0000
@@ -468,7 +468,7 @@
      The result is truncated toward negative infinity and negative,
      if the operands signs differ.
      The following is always true:
-	(receiver // aNumber) * aNumber + (receiver \\ aNUmber) = receiver
+        (receiver // aNumber) * aNumber + (receiver \\ aNUmber) = receiver
     "
 
     |cls divMod quo abs "{ Class: SmallInteger }" n|
@@ -481,33 +481,38 @@
      Use a special method for this case ...
     "
     (cls == SmallInteger) ifTrue:[
-	abs := aNumber.
-	abs := abs abs.
-	(abs between:1 and:16r00ffffff) ifTrue:[
-	    divMod := self absFastDivMod:abs.
-	] ifFalse:[
-	    n := abs asLargeInteger.
-	].
+        abs := aNumber.
+        abs := abs abs.
+        (abs between:1 and:16r00ffffff) ifTrue:[
+            divMod := self absFastDivMod:abs.
+        ] ifFalse:[
+            n := abs asLargeInteger.
+        ].
     ] ifFalse:[
-	"
-	 if the argument is not a largeInteger, coerce
-	"
-	(cls == self class) ifFalse:[
-	    ^ self retry:#// coercing:aNumber
-	].
-	n := aNumber
+        "
+         if the argument is not a largeInteger, coerce
+        "
+        (cls == self class) ifFalse:[
+            ^ self retry:#// coercing:aNumber
+        ].
+        n := aNumber
     ].
 
     divMod isNil ifTrue:[
-	divMod := self absDivMod:n.
+        divMod := self absDivMod:n.
     ].
     quo := divMod at:1.
     (sign == aNumber sign) ifFalse:[
-	"/ adjust for truncation if negative and there is a remainder ...
-	quo := quo sign:-1.
-	(divMod at:2) == 0 ifFalse:[
-	    ^ quo - 1
-	].
+        "/ adjust for truncation if negative and there is a remainder ...
+        "/ be careful: there is one special case to care for here:
+        "/ if quo is maxInt+1, the negation can be represented as a smallInt.
+        quo := quo sign:-1.
+        (divMod at:2) == 0 ifFalse:[
+            ^ quo - 1
+        ].
+        quo digitLength == SmallInteger maxBytes ifTrue:[
+            ^ quo compressed
+        ].
     ].
     ^ quo
 
@@ -1116,102 +1121,94 @@
      idx0 "{ Class: SmallInteger }"
      byte|
 
-    sz := digitByteArray size.
     idx0 := 1.
 
-%{
+%{  
+    OBJ __digitByteArray = __INST(digitByteArray);
+
     /*
      * quickly advance over full 0-words
      */
-    if (__isByteArray(__INST(digitByteArray))) {
-	int __sz = __intVal(sz);
-	unsigned char *__bP = __byteArrayVal(__INST(digitByteArray));
-	unsigned char *__bP0 = __bP;
+    if (__isByteArray(__digitByteArray)) {
+        int __sz = __byteArraySize(__digitByteArray);
+        unsigned char *__bP = __byteArrayVal(__digitByteArray);
+        unsigned char *__bP0 = __bP;
+
+        sz = _MKSMALLINT(__sz);
 
 #ifdef __UNROLL_LOOPS__
-	while (__sz > (sizeof(INT) * 4)) {
-	    if ( ((INT *)__bP)[0] != 0 ) break;
-	    if ( ((INT *)__bP)[1] != 0 ) {
-		__sz -= sizeof(INT);
-		__bP += sizeof(INT);
-		break;
-	    }
-	    if ( ((INT *)__bP)[2] != 0 ) {
-		__sz -= sizeof(INT) * 2;
-		__bP += sizeof(INT) * 2;
-		break;
-	    }
-	    if ( ((INT *)__bP)[3] != 0 ) {
-		__sz -= sizeof(INT) * 3;
-		__bP += sizeof(INT) * 3;
-		break;
-	    }
-	    __sz -= sizeof(INT) * 4;
-	    __bP += sizeof(INT) * 4;
-	}
+        while (__sz > (sizeof(INT) * 4)) {
+            if (( ((INT *)__bP)[0] 
+                 | ((INT *)__bP)[1] 
+                 | ((INT *)__bP)[2] 
+                 | ((INT *)__bP)[3] ) != 0) break;
+            __sz -= sizeof(INT) * 4;
+            __bP += sizeof(INT) * 4;
+        }
 #endif
-	while (__sz > sizeof(INT)) {
-	    if ( ((INT *)__bP)[0] != 0 ) break;
-	    __sz -= sizeof(INT);
-	    __bP += sizeof(INT);
-	}
-	while (__sz > 0) {
-	    unsigned int c;
-
-	    if ( (c = *__bP) != 0 ) {
-		int bitIdx = (__bP - __bP0) * 8;
+        while (__sz > sizeof(INT)) {
+            if ( ((INT *)__bP)[0] != 0 ) break;
+            __sz -= sizeof(INT);
+            __bP += sizeof(INT);
+        }
+        while (__sz > 0) {
+            unsigned int c;
+
+            if ( (c = *__bP) != 0 ) {
+                int bitIdx = (__bP - __bP0) * 8;
 #ifdef __BSF
-		{
-		    int index;
-		    int t = c;
-
-		    index = __BSF(t);
-		    RETURN ( __mkSmallInteger(index + 1 + bitIdx) );
-		}
+                {
+                    int index;
+                    int t = c;
+
+                    index = __BSF(t);
+                    RETURN ( __mkSmallInteger(index + 1 + bitIdx) );
+                }
 #else
-		if (c & 0x0F) {
-		    if (c & 0x03) {
-			if (c & 0x01) {
-			    RETURN ( __mkSmallInteger( bitIdx + 1) );
-			} else {
-			    RETURN ( __mkSmallInteger( bitIdx + 2) );
-			}
-		    } else {
-			if (c & 0x04) {
-			    RETURN ( __mkSmallInteger( bitIdx + 3) );
-			} else {
-			    RETURN ( __mkSmallInteger( bitIdx + 4) );
-			}
-		    }
-		} else {
-		    if (c & 0x30) {
-			if (c & 0x10) {
-			    RETURN ( __mkSmallInteger( bitIdx + 5) );
-			} else {
-			    RETURN ( __mkSmallInteger( bitIdx + 6) );
-			}
-		    } else {
-			if (c & 0x40) {
-			    RETURN ( __mkSmallInteger( bitIdx + 7) );
-			} else {
-			    RETURN ( __mkSmallInteger( bitIdx + 8) );
-			}
-		    }
-		}
+                if (c & 0x0F) {
+                    if (c & 0x03) {
+                        if (c & 0x01) {
+                            RETURN ( __mkSmallInteger( bitIdx + 1) );
+                        } else {
+                            RETURN ( __mkSmallInteger( bitIdx + 2) );
+                        }
+                    } else {
+                        if (c & 0x04) {
+                            RETURN ( __mkSmallInteger( bitIdx + 3) );
+                        } else {
+                            RETURN ( __mkSmallInteger( bitIdx + 4) );
+                        }
+                    }
+                } else {
+                    if (c & 0x30) {
+                        if (c & 0x10) {
+                            RETURN ( __mkSmallInteger( bitIdx + 5) );
+                        } else {
+                            RETURN ( __mkSmallInteger( bitIdx + 6) );
+                        }
+                    } else {
+                        if (c & 0x40) {
+                            RETURN ( __mkSmallInteger( bitIdx + 7) );
+                        } else {
+                            RETURN ( __mkSmallInteger( bitIdx + 8) );
+                        }
+                    }
+                }
 #endif
-		break;
-	    }
-	    __sz--;
-	    __bP++;
-	}
-	idx0 = __mkSmallInteger( __bP - __bP0 + 1 );
+                break;
+            }
+            __sz--;
+            __bP++;
+        }
+        idx0 = __mkSmallInteger( __bP - __bP0 + 1 );
     }
 %}.
+
     "/ never actually reached
     idx0 to:sz do:[:digitIndex |
-	(byte := digitByteArray at:digitIndex) ~~ 0 ifTrue:[
-	    ^ (digitIndex-1)*8 + (byte lowBit)
-	]
+        (byte := digitByteArray at:digitIndex) ~~ 0 ifTrue:[
+            ^ (digitIndex-1)*8 + (byte lowBit)
+        ]
     ].
     ^ 0 "/ should not happen
 
@@ -1235,24 +1232,24 @@
      ((1 bitShift:64)-1) highBit
 
      1 to:1000 do:[:idx |
-	self assert:(( 1 bitShift:idx) lowBit = (idx+1)).
-	self assert:(( 1 bitShift:idx) lowBit = ( 1 bitShift:idx) highBit).
-	self assert:(( 3 bitShift:idx) lowBit = (idx+1)).
-	self assert:(( 7 bitShift:idx) lowBit = (idx+1)).
-	self assert:(( 15 bitShift:idx) lowBit = (idx+1)).
-	self assert:(( 31 bitShift:idx) lowBit = (idx+1)).
-	self assert:(( 63 bitShift:idx) lowBit = (idx+1)).
-	self assert:(( 127 bitShift:idx) lowBit = (idx+1)).
-	self assert:(( 255 bitShift:idx) lowBit = (idx+1)).
+        self assert:(( 1 bitShift:idx) lowBit = (idx+1)).
+        self assert:(( 1 bitShift:idx) lowBit = ( 1 bitShift:idx) highBit).
+        self assert:(( 3 bitShift:idx) lowBit = (idx+1)).
+        self assert:(( 7 bitShift:idx) lowBit = (idx+1)).
+        self assert:(( 15 bitShift:idx) lowBit = (idx+1)).
+        self assert:(( 31 bitShift:idx) lowBit = (idx+1)).
+        self assert:(( 63 bitShift:idx) lowBit = (idx+1)).
+        self assert:(( 127 bitShift:idx) lowBit = (idx+1)).
+        self assert:(( 255 bitShift:idx) lowBit = (idx+1)).
      ]
 
      |num|
 
      num := (1 bitShift:1000).
      Time millisecondsToRun:[
-	100000 timesRepeat:[
-	    num lowBit
-	]
+        1000000 timesRepeat:[
+            num lowBit
+        ]
      ]
     "
 
@@ -4953,12 +4950,13 @@
 !LargeInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Id: LargeInteger.st 10480 2009-12-02 21:30:55Z vranyj1 $'
+    ^ '$Id: LargeInteger.st 10505 2010-03-08 21:39:02Z vranyj1 $'
 !
 
 version_CVS
-    ^ '§Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.197 2009/10/04 21:07:18 cg Exp §'
+    ^ '§Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.199 2010/02/26 20:20:38 cg Exp §'
 ! !
 
 
 
+