LargeInteger.st
changeset 4187 3dc575bd3915
parent 4185 375439993eb7
child 4188 d0339e17d64a
--- a/LargeInteger.st	Fri May 14 12:26:44 1999 +0200
+++ b/LargeInteger.st	Fri May 14 17:20:07 1999 +0200
@@ -2910,8 +2910,7 @@
      and argument. The receiver must be >= the argument.
      The receiver must be a temporary scratch-number"
 
-    |done
-     otherDigitByteArray
+    |otherDigitByteArray
      len1   "{ Class: SmallInteger }"
      len2   "{ Class: SmallInteger }"
      index  "{ Class: SmallInteger }"
@@ -2925,42 +2924,92 @@
     otherDigitByteArray := aLargeInteger digits.
     len2 := otherDigitByteArray size.
     len2 > len1 ifTrue:[
-	[(otherDigitByteArray at:len2) == 0] whileTrue:[
-	    len2 := len2 - 1
-	].
-	len2 > len1 ifTrue:[
-	    self halt "/ may not be called that way
-	].
+        [(otherDigitByteArray at:len2) == 0] whileTrue:[
+            len2 := len2 - 1
+        ].
+        len2 > len1 ifTrue:[
+            self halt "/ may not be called that way
+        ].
     ].
-
-    index := 1.
-    borrow := 0.
-
-    done := false.
-    [index <= len1] whileTrue:[
-	diff := borrow.
-	diff := diff + (digitByteArray basicAt:index).
-	index <= len2 ifTrue:[
-	    diff := diff - (otherDigitByteArray basicAt:index).
-	].
-
-	"/ workaround for
-	"/ gcc code generator bug
-
-	(diff >= 0) ifTrue:[
-	    borrow := 0
-	] ifFalse:[
-	    borrow := -1.
-	    diff := diff + 16r100
-	].
-	diff ~~ 0 ifTrue:[
-	    notZero := true
-	].
-	digitByteArray basicAt:index put:diff.
-	index := index + 1
-    ].
-
-    ^ notZero
+    "/ knowing that len2 is <= len1
+%{
+    OBJ _digitByteArray = __INST(digitByteArray);
+
+    if (__isByteArray(_digitByteArray)
+     && __isByteArray(otherDigitByteArray)) {
+        int _len1 = __intVal(len1), 
+            _len2 = __intVal(len2);
+        unsigned char *_myDigits, *_otherDigits, *_newDigits;
+        int _index = 1, _borrow = 0;
+        int _diff;
+        int anyBitNonZero = 0;
+
+        _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+        _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+
+        while (_index <= _len2) {
+            _diff = _borrow + _myDigits[_index - 1];
+            _diff -= _otherDigits[_index - 1];
+            if (_diff >= 0) {
+                _borrow = 0;
+            } else {
+                _borrow = -1;
+                diff += 0x100;
+            }
+            _myDigits[_index - 1] = _diff;
+            anyBitNonZero |= _diff;
+            _index++;
+        }
+        while (_index <= _len1) {
+            _diff = _borrow + _myDigits[_index - 1];
+            if (_diff >= 0) {
+                _myDigits[_index - 1] = _diff;
+                anyBitNonZero |= _diff;
+                _index++;
+                while (_index <= _len1) {
+                    anyBitNonZero |= _myDigits[_index - 1];
+                    _index++;
+                }
+                break;
+            } else {
+                _borrow = -1;
+                diff += 0x100;
+            }
+            _myDigits[_index - 1] = _diff;
+            anyBitNonZero |= _diff;
+            _index++;
+        }
+        RETURN (anyBitNonZero ? true : false);
+    }
+%}.
+
+"/    index := 1.
+"/    borrow := 0.
+"/
+"/    [index <= len1] whileTrue:[
+"/        diff := borrow.
+"/        diff := diff + (digitByteArray basicAt:index).
+"/        index <= len2 ifTrue:[
+"/            diff := diff - (otherDigitByteArray basicAt:index).
+"/        ].
+"/
+"/        "/ workaround for
+"/        "/ gcc code generator bug
+"/
+"/        (diff >= 0) ifTrue:[
+"/            borrow := 0
+"/        ] ifFalse:[
+"/            borrow := -1.
+"/            diff := diff + 16r100
+"/        ].
+"/        diff ~~ 0 ifTrue:[
+"/            notZero := true
+"/        ].
+"/        digitByteArray basicAt:index put:diff.
+"/        index := index + 1
+"/    ].
+"/
+"/    ^ notZero
 
     "Created: / 5.11.1996 / 16:23:47 / cg"
     "Modified: / 5.11.1996 / 18:56:50 / cg"
@@ -2976,72 +3025,72 @@
     OBJ __digits = __INST(digitByteArray);
 
     if (__isByteArray(__digits)) {
-	int __nBytes = __byteArraySize(__digits);
-	unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
-	unsigned INT __this, __next;
-	int __idx;
-
-	if (__nBytes == 1) {
-	    __bp[0] >>= 1;
-	    RETURN (self);
-	}
-
-	__idx = 1;
+        int __nBytes = __byteArraySize(__digits);
+        unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
+        unsigned INT __this, __next;
+        int __idx;
+
+        if (__nBytes == 1) {
+            __bp[0] >>= 1;
+            RETURN (self);
+        }
+
+        __idx = 1;
 
 #if defined(alpha64)
-	if (sizeof(unsigned INT) == 8) {
-	    if ((__idx + 8) < __nBytes) {
-		__this = ((unsigned INT *)__bp)[0];
-
-		while ((__idx + 8) < __nBytes) {
-		    __next = ((unsigned INT *)__bp)[1];
-		    __this = (__this >> 1) /* & 0x7FFFFFFFFFFFFFF */;
-		    __this |= __next << 63;
-		    ((unsigned INT *)__bp)[0] = __this;
-		    __this = __next;
-		    __bp += 8;
-		    __idx += 8;
-		}
-	    }
-	}
+        if (sizeof(unsigned INT) == 8) {
+            if ((__idx + 8) < __nBytes) {
+                __this = ((unsigned INT *)__bp)[0];
+
+                while ((__idx + 8) < __nBytes) {
+                    __next = ((unsigned INT *)__bp)[1];
+                    __this = (__this >> 1) /* & 0x7FFFFFFFFFFFFFF */;
+                    __this |= __next << 63;
+                    ((unsigned INT *)__bp)[0] = __this;
+                    __this = __next;
+                    __bp += 8;
+                    __idx += 8;
+                }
+            }
+        }
 #else
 # if defined(__LSBFIRST) || defined(i386) /* XXX actually: LSB_FIRST */
-	if (sizeof(unsigned INT) == 4) {
-	    if ((__idx + 4) < __nBytes) {
-		__this = ((unsigned INT *)__bp)[0];
-
-		while ((__idx + 4) < __nBytes) {
-		    __next = ((unsigned INT *)__bp)[1];
-		    __this = (__this >> 1) /* & 0x7FFFFFF */;
-		    __this |= __next << 31;
-		    ((unsigned INT *)__bp)[0] = __this;
-		    __this = __next;
-		    __bp += 4;
-		    __idx += 4;
-		}
-	    }
-	}
+        if (sizeof(unsigned INT) == 4) {
+            if ((__idx + 4) < __nBytes) {
+                __this = ((unsigned INT *)__bp)[0];
+
+                while ((__idx + 4) < __nBytes) {
+                    __next = ((unsigned INT *)__bp)[1];
+                    __this = (__this >> 1) /* & 0x7FFFFFF */;
+                    __this |= __next << 31;
+                    ((unsigned INT *)__bp)[0] = __this;
+                    __this = __next;
+                    __bp += 4;
+                    __idx += 4;
+                }
+            }
+        }
 # endif
 #endif
 
-	__this = __bp[0];
-	while (__idx < __nBytes) {
-	    __next = __bp[1];
-	    __this >>= 1;
-	    __this |= __next << 7;
-	    __bp[0] = __this;
-	    __this = __next;
-	    __bp++;
-	    __idx++;
-	}
-	__bp[0] = __this >> 1;
-	RETURN (self);
+        __this = __bp[0];
+        while (__idx < __nBytes) {
+            __next = __bp[1];
+            __this >>= 1;
+            __this |= __next << 7;
+            __bp[0] = __this;
+            __this = __next;
+            __bp++;
+            __idx++;
+        }
+        __bp[0] = __this >> 1;
+        RETURN (self);
     }
 %}.
     self primitiveFailed
 
     "
-     100000 asLargeInteger div2   
+     100000 asLargeInteger div2      
      1000000000000000000000000000 div2 
     "
 
@@ -3198,5 +3247,5 @@
 !LargeInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.94 1999-05-12 12:06:55 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.95 1999-05-14 15:20:07 cg Exp $'
 ! !