--- 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 $'
! !