LargeInteger.st
changeset 4190 9fdc42eea567
parent 4189 cbe91dfb662e
child 4191 d6376725d99d
--- a/LargeInteger.st	Fri May 14 17:50:10 1999 +0200
+++ b/LargeInteger.st	Fri May 14 18:09:32 1999 +0200
@@ -2361,7 +2361,7 @@
      borrow "{ Class: SmallInteger }"
      diff   "{ Class: SmallInteger }"
      carry  "{ Class: SmallInteger }" 
-     lResult|
+     lResult ok|
 
     len1 := digitByteArray size.
     otherDigitByteArray := aLargeInteger digits.
@@ -2372,71 +2372,133 @@
     result sign:newSign.
     resultDigitByteArray := result digits.
 
-    index := 1.
-    borrow := 0.
-
-    done := false.
-    [done] whileFalse:[
-	diff := borrow.
-	(index <= len1) ifTrue:[
-	    diff := diff + (digitByteArray basicAt:index).
-	    (index <= len2) ifTrue:[
-		diff := diff - (otherDigitByteArray basicAt:index)
-	    ]
-	] ifFalse:[
-	    (index <= len2) ifTrue:[
-		diff := diff - (otherDigitByteArray basicAt:index)
-	    ] ifFalse:[
-		"end reached"
-		done := true
-	    ]
-	].
-
-	"/ workaround for
-	"/ gcc code generator bug
-
-	(diff >= 0) ifTrue:[
-	    borrow := 0
-	] ifFalse:[
-	    borrow := -1.
-	    diff := diff + 16r100
-	].
-
-"/        (diff < 0) ifTrue:[
-"/            borrow := -1.
-"/            diff := diff + 16r100
-"/        ] ifFalse:[
-"/            borrow := 0
-"/        ].
-
-	resultDigitByteArray basicAt:index put:diff.
-	index := index + 1
+%{
+    OBJ _digitByteArray = __INST(digitByteArray);
+
+    if (__isByteArray(_digitByteArray)
+     && __isByteArray(otherDigitByteArray)
+     && __isByteArray(resultDigitByteArray)) {
+        int __len1 = __intVal(len1);
+        int __len2 = __intVal(len2);
+        int __minLen = __len1 < __len2 ? __len1 : __len2;
+        int __index, __borrow = 0, __diff;
+        unsigned char *__myDigits, *__otherDigits, *__resultDigits;
+        
+        ok = true;
+
+        __resultDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+        __otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+        __myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+
+        __index = 1;
+        while (__index <= __minLen) {
+            __diff = __borrow + __myDigits[__index-1] - __otherDigits[__index-1];
+            if (__diff >= 0) {
+                __borrow = 0;
+            } else {
+                __borrow = -1;
+                __diff += 0x100;
+            }
+            __resultDigits[__index-1] = __diff;
+            __index++;
+        }
+        if (__len1 > __len2) {
+            while (__index <= __len1) {
+                __diff = __borrow + __myDigits[__index-1];
+                if (__diff >= 0) {
+                    __borrow = 0;
+                } else {
+                    __borrow = -1;
+                    __diff += 0x100;
+                }
+                __resultDigits[__index-1] = __diff;
+                __index++;
+            }
+        } else {
+            if (__len2 > __len1) {
+                while (__index <= __len2) {
+                    __diff = __borrow - __otherDigits[__index-1];
+                    if (__diff >= 0) {
+                        __borrow = 0;
+                    } else {
+                        __borrow = -1;
+                        __diff += 0x100;
+                    }
+                    __resultDigits[__index-1] = __diff;
+                    __index++;
+                }
+            }
+        }
+        borrow = __MKSMALLINT(__borrow);
+    }
+%}.
+    ok == true ifFalse:[
+        index := 1.
+        borrow := 0.
+
+        done := false.
+        [done] whileFalse:[
+            diff := borrow.
+            (index <= len1) ifTrue:[
+                diff := diff + (digitByteArray basicAt:index).
+                (index <= len2) ifTrue:[
+                    diff := diff - (otherDigitByteArray basicAt:index)
+                ]
+            ] ifFalse:[
+                (index <= len2) ifTrue:[
+                    diff := diff - (otherDigitByteArray basicAt:index)
+                ] ifFalse:[
+                    "end reached"
+                    done := true
+                ]
+            ].
+
+            "/ workaround for
+            "/ gcc code generator bug
+
+            (diff >= 0) ifTrue:[
+                borrow := 0
+            ] ifFalse:[
+                borrow := -1.
+                diff := diff + 16r100
+            ].
+
+    "/        (diff < 0) ifTrue:[
+    "/            borrow := -1.
+    "/            diff := diff + 16r100
+    "/        ] ifFalse:[
+    "/            borrow := 0
+    "/        ].
+
+            resultDigitByteArray basicAt:index put:diff.
+            index := index + 1
+        ].
     ].
 
     (borrow ~~ 0) ifTrue:[
-	"/ must generate 255's complement
-
-	result sign:-1.
-	[index <= lResult] whileTrue:[
-	    resultDigitByteArray basicAt:index put:16rFF.
-	    index := index + 1.
-	].
-	index := resultDigitByteArray size.
-	[index > 0] whileTrue:[
-	    resultDigitByteArray basicAt:index put:(255 - (resultDigitByteArray at:index)).
-	    index := index -1.
-	].
-
-	index := 1.
-	carry := 1.
-	[carry ~~ 0] whileTrue:[
-	    (index <= lResult) ifTrue:[
-		carry := (resultDigitByteArray basicAt:index) + carry.
-	    ].
-	    resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF).
-	    carry := carry bitShift:-8.
-	    index := index + 1
-	].
+        "/ must generate 255's complement
+
+        result sign:-1.
+        [index <= lResult] whileTrue:[
+            resultDigitByteArray basicAt:index put:16rFF.
+            index := index + 1.
+        ].
+        index := resultDigitByteArray size.
+        [index > 0] whileTrue:[
+            resultDigitByteArray basicAt:index put:(255 - (resultDigitByteArray at:index)).
+            index := index -1.
+        ].
+
+        index := 1.
+        carry := 1.
+        [carry ~~ 0] whileTrue:[
+            (index <= lResult) ifTrue:[
+                carry := (resultDigitByteArray basicAt:index) + carry.
+            ].
+            resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF).
+            carry := carry bitShift:-8.
+            index := index + 1
+        ].
     ].
     ^ result compressed
 
@@ -3251,5 +3313,5 @@
 !LargeInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.97 1999-05-14 15:50:10 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.98 1999-05-14 16:09:32 cg Exp $'
 ! !