--- a/LargeInteger.st Wed May 19 23:13:50 1999 +0200
+++ b/LargeInteger.st Thu May 20 00:16:51 1999 +0200
@@ -1942,7 +1942,7 @@
((aSmallInteger < (SmallInteger minVal + 255))
or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
- ^ self absMinus:(LargeInteger value:aSmallInteger) sign:newSign.
+ ^ self absMinus:(LargeInteger value:aSmallInteger) sign:newSign.
].
len := digitByteArray size.
@@ -1957,72 +1957,69 @@
%{
if (__isByteArray(__INST(digitByteArray))
&& __isByteArray(resultDigitByteArray)) {
- unsigned int __borrow = __intVal(borrow);
- int __diff;
- int __index = 1;
- int __len = __intVal(len);
- unsigned char *__digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
- unsigned char *__resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+ unsigned int __borrow = __intVal(borrow);
+ int __diff;
+ int __index = 1;
+ int __len = __intVal(len);
+ unsigned char *__digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
+ unsigned char *__resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
#if defined(__LSBFIRST) || defined(i386)
- /* subtract short-wise */
- while (__index < __len) {
- __diff = ((unsigned short *)(__digitP+__index-1))[0] - (__borrow & 0xFFFF);
- __borrow >>= 16;
- if (__diff < 0) {
- __diff += 0x10000;
- __borrow++;
- }
- ((unsigned short *)(__resultP+__index-1))[0] = __diff;
- __index += 2;
- }
+ /* subtract short-wise */
+ while (__index < __len) {
+ __diff = ((unsigned short *)(__digitP+__index-1))[0] - (__borrow & 0xFFFF);
+ __borrow >>= 16;
+ if (__diff < 0) {
+ __diff += 0x10000;
+ __borrow++;
+ }
+ ((unsigned short *)(__resultP+__index-1))[0] = __diff;
+ __index += 2;
+ }
#endif
- while (__index <= __len) {
- __diff = __digitP[__index-1] - (__borrow & 0xFF);
- __borrow >>= 8;
- if (__diff < 0) {
- __diff += 0x100;
- __borrow++;
- }
- __resultP[__index-1] = __diff;
- __index++;
- }
- lastDigit = __MKSMALLINT( __resultP[__index-1-1] );
- ok = true;
+ while (__index <= __len) {
+ __diff = __digitP[__index-1] - (__borrow & 0xFF);
+ __borrow >>= 8;
+ if (__diff < 0) {
+ __diff += 0x100;
+ __borrow++;
+ }
+ __resultP[__index-1] = __diff;
+ __index++;
+ }
+ lastDigit = __MKSMALLINT( __resultP[__index-1-1] );
+ ok = true;
}
%}.
ok == true ifFalse:[ "/ cannot happen
- index := 1.
- [borrow ~~ 0] whileTrue:[
- (index <= len) ifTrue:[
- diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF).
- borrow := borrow bitShift:-8.
- diff < 0 ifTrue:[
- diff := diff + 256.
- borrow := borrow + 1.
- ]
- ] ifFalse:[
- diff := borrow bitAnd:255.
- borrow := borrow bitShift:-8.
- ].
- resultDigitByteArray basicAt:index put:(lastDigit := diff).
- index := index + 1
- ].
- [index <= len] whileTrue:[
- resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index).
- index := index + 1
- ].
- (index <= rsltLen) ifTrue:[
- lastDigit := 0.
- ]
+ index := 1.
+ [borrow ~~ 0] whileTrue:[
+ (index <= len) ifTrue:[
+ diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF).
+ borrow := borrow bitShift:-8.
+ diff < 0 ifTrue:[
+ diff := diff + 256.
+ borrow := borrow + 1.
+ ]
+ ] ifFalse:[
+ diff := borrow bitAnd:255.
+ borrow := borrow bitShift:-8.
+ ].
+ resultDigitByteArray basicAt:index put:(lastDigit := diff).
+ index := index + 1
+ ].
+ [index <= len] whileTrue:[
+ resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index).
+ index := index + 1
+ ].
+ (index <= rsltLen) ifTrue:[
+ lastDigit := 0.
+ ]
].
-"/ Transcript showCR:SmallInteger maxBytes.
-"/ self halt.
(lastDigit == 0 or:[rsltLen == SmallInteger maxBytes]) ifTrue:[
-"/ self halt.
- ^ result compressed.
+ ^ result compressed.
].
^ result
@@ -2056,11 +2053,17 @@
((aSmallInteger < (SmallInteger minVal + 255))
or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
- ^ self absPlus:(LargeInteger value:aSmallInteger) sign:newSign.
+ ^ self absPlus:(LargeInteger value:aSmallInteger) sign:newSign.
].
- len := digitByteArray size.
- rsltLen := len + 1.
+ len := rsltLen := digitByteArray size.
+ "/
+ "/ there can only be an overflow from the high byte,
+ "/ if it is 255 (since the other number is definitely smaller)
+ "/
+ (digitByteArray at:len) == 16rFF ifTrue:[
+ rsltLen := len + 1.
+ ].
result := self class basicNew numberOfDigits:rsltLen.
result sign:newSign.
@@ -2070,172 +2073,163 @@
if (__isByteArray(__INST(digitByteArray))
&& __isByteArray(resultDigitByteArray)
&& __isSmallInteger(aSmallInteger)) {
- /* carry is NOT unsigned (see negation below) */
- INT __carry = __intVal(aSmallInteger);
- int __index = 1;
- int __len = __intVal(len);
- unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
- unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element);
- unsigned int __lastDigit = 0;
- INT __ptrDelta = __dst - __src;
- unsigned char *__srcLast = __src + __len - 1;
- unsigned char *__dstLast = __dst + __intVal(rsltLen) - 1;
-
- if (__carry < 0) {
- __carry = -__carry;
- }
+ /* carry is NOT unsigned (see negation below) */
+ INT __carry = __intVal(aSmallInteger);
+ int __index = 1;
+ int __len = __intVal(len);
+ unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
+ unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element);
+ INT __ptrDelta = __dst - __src;
+ unsigned char *__srcLast = __src + __len - 1;
+ unsigned char *__dstLast = __dst + __intVal(rsltLen) - 1;
+
+ if (__carry < 0) {
+ __carry = -__carry;
+ }
#if defined(__LSBFIRST) || defined(i386) || defined(alpha)
# if defined(i386) && defined(__GNUC__)
- /*
- * add long-wise
- */
- while (__src <= __srcLast-3) {
- int __sum;
-
- asm ("addl %%edx,%%eax \n
- movl $0,%%edx \n
- adcl $0,%%edx"
- : "=d" ((unsigned long)(__carry)),
- "=a" ((unsigned long)(__sum))
- : "0" ((unsigned long)(__carry)),
- "1" ((unsigned long)(((unsigned *)__src)[0])) );
-
- ((unsigned *)(__src + __ptrDelta))[0] = __lastDigit = __sum;
- __src += 4;
- if (__carry == 0) {
- while (__src <= __srcLast-3) {
- /* copy over */
- ((unsigned *)(__src + __ptrDelta))[0] = ((unsigned *)__src)[0];
- __src += 4;
- }
- __lastDigit = 0;
- break;
- }
- }
- __lastDigit >>= 24; /* only the high-byte counts */
+ /*
+ * add long-wise
+ */
+ while (__src <= __srcLast-3) {
+ int __sum;
+
+ asm ("addl %%edx,%%eax \n
+ movl $0,%%edx \n
+ adcl $0,%%edx"
+ : "=d" ((unsigned long)(__carry)),
+ "=a" ((unsigned long)(__sum))
+ : "0" ((unsigned long)(__carry)),
+ "1" ((unsigned long)(((unsigned *)__src)[0])) );
+
+ ((unsigned *)(__src + __ptrDelta))[0] = __sum;
+ __src += 4;
+ if (__carry == 0) {
+ while (__src <= __srcLast-3) {
+ /* copy over */
+ ((unsigned *)(__src + __ptrDelta))[0] = ((unsigned *)__src)[0];
+ __src += 4;
+ }
+ break;
+ }
+ }
# else
# if defined(i386) && defined(WIN32)
- /*
- * add long-wise
- */
- while (__src <= __srcLast-3) {
- unsigned int __sum;
-
- __sum = ((unsigned int *)__src)[0];
- asm {
- mov eax, __sum
- add eax, __carry
- mov edx, 0
- adc edx, 0
- mov __sum, eax
- mov __carry, edx
- }
-
- ((unsigned *)(__src + __ptrDelta))[0] = __lastDigit = __sum;
- __src += 4;
- if (__carry == 0) {
- while (__src <= __srcLast-3) {
- /* copy over */
- ((unsigned *)(__src + __ptrDelta))[0] = ((unsigned *)__src)[0];
- __src += 4;
- }
- __lastDigit = 0;
- break;
- }
- }
- __lastDigit >>= 24; /* only the high-byte counts */
+ /*
+ * add long-wise
+ */
+ while (__src <= __srcLast-3) {
+ unsigned int __sum;
+
+ __sum = ((unsigned int *)__src)[0];
+ asm {
+ mov eax, __sum
+ add eax, __carry
+ mov edx, 0
+ adc edx, 0
+ mov __sum, eax
+ mov __carry, edx
+ }
+
+ ((unsigned *)(__src + __ptrDelta))[0] = __sum;
+ __src += 4;
+ if (__carry == 0) {
+ while (__src <= __srcLast-3) {
+ /* copy over */
+ ((unsigned *)(__src + __ptrDelta))[0] = ((unsigned *)__src)[0];
+ __src += 4;
+ }
+ break;
+ }
+ }
# else
# ifdef alpha64
- /*
- * add long-wise
- */
- while (__src <= (__srcLast-3)) {
- unsigned INT __sum;
-
- __sum = ((unsigned int *)__src)[0] + __carry;
- ((unsigned int *)(__src + __ptrDelta))[0] = __lastDigit = __sum /* & 0xFFFF */;
- __src += 4;
- __carry = __sum >> 32;
- if (__carry == 0) {
- while (__src <= (__srcLast-3)) {
- /* copy over */
- ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
- __src += 4;
- }
- __lastDigit = 0;
- break;
- }
- }
- __lastDigit >>= 24; /* only the high-byte counts */
+ /*
+ * add long-wise
+ */
+ while (__src <= (__srcLast-3)) {
+ unsigned INT __sum;
+
+ __sum = ((unsigned int *)__src)[0] + __carry;
+ ((unsigned int *)(__src + __ptrDelta))[0] = __sum /* & 0xFFFF */;
+ __src += 4;
+ __carry = __sum >> 32;
+ if (__carry == 0) {
+ while (__src <= (__srcLast-3)) {
+ /* copy over */
+ ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
+ __src += 4;
+ }
+ break;
+ }
+ }
# endif /* alpha64 */
# endif /* i386 & WIN32 */
# endif /* i386 & GNUC */
- /*
- * add short-wise
- */
- while (__src < __srcLast) {
- __carry += ((unsigned short *)__src)[0];
- ((unsigned short *)(__src + __ptrDelta))[0] = __lastDigit = __carry /* & 0xFFFF */;
- __carry >>= 16;
- __src += 2;
- }
- if (__src <= __srcLast) {
- __carry += __src[0];
- __src[__ptrDelta] = __lastDigit = __carry /* & 0xFF */;
- __carry >>= 8;
- __src++;
- } else {
- __lastDigit >>= 8; /* only the high-byte counts */
- }
+ /*
+ * add short-wise
+ */
+ while (__src < __srcLast) {
+ __carry += ((unsigned short *)__src)[0];
+ ((unsigned short *)(__src + __ptrDelta))[0] = __carry /* & 0xFFFF */;
+ __carry >>= 16;
+ __src += 2;
+ }
+ if (__src <= __srcLast) {
+ __carry += __src[0];
+ __src[__ptrDelta] = __carry /* & 0xFF */;
+ __carry >>= 8;
+ __src++;
+ }
#else /* not __LSBFIRST */
- while (__src <= __srcLast) {
- __carry += __src[0];
- __src[__ptrDelta] = __lastDigit = __carry /* & 0xFF */;
- __carry >>= 8;
- __src++;
- }
+ while (__src <= __srcLast) {
+ __carry += __src[0];
+ __src[__ptrDelta] = __carry /* & 0xFF */;
+ __carry >>= 8;
+ __src++;
+ }
#endif /* __LSBFIRST */
- __dst = __src + __ptrDelta;
- while (__dst <= __dstLast) {
- __dst[0] = __lastDigit = __carry /* & 0xFF */;
- __carry >>= 8;
- __dst++;
- }
-
- if (lastDigit) {
- RETURN (result);
- }
- ok = true;
+ __dst = __src + __ptrDelta;
+ while (__dst <= __dstLast) {
+ __dst[0] = __carry /* & 0xFF */;
+ __carry >>= 8;
+ __dst++;
+ }
+
+ if (__dst[-1]) { /* lastDigit */
+ RETURN (result);
+ }
+ ok = true;
}
%}.
ok ~~ true ifTrue:[
- index := 1.
- carry := aSmallInteger abs.
-
- [carry ~~ 0] whileTrue:[
- (index <= len) ifTrue:[
- carry := (digitByteArray basicAt:index) + carry.
- ].
- resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF).
- carry := carry bitShift:-8.
- index := index + 1
- ].
-
- (index <= rsltLen) ifTrue:[
- [index <= len] whileTrue:[
- resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index).
- index := index + 1
- ].
- lastDigit := 0.
- ].
-
- lastDigit ~~ 0 ifTrue:[
- ^ result
- ].
+ index := 1.
+ carry := aSmallInteger abs.
+
+ [carry ~~ 0] whileTrue:[
+ (index <= len) ifTrue:[
+ carry := (digitByteArray basicAt:index) + carry.
+ ].
+ resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF).
+ carry := carry bitShift:-8.
+ index := index + 1
+ ].
+
+ (index <= rsltLen) ifTrue:[
+ [index <= len] whileTrue:[
+ resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index).
+ index := index + 1
+ ].
+ lastDigit := 0.
+ ].
+
+ lastDigit ~~ 0 ifTrue:[
+ ^ result
+ ].
].
^ result compressed
@@ -2345,6 +2339,7 @@
borrow "{ Class: SmallInteger }"
diff "{ Class: SmallInteger }"
carry "{ Class: SmallInteger }"
+ lastDigit
lResult ok|
len1 := digitByteArray size.
@@ -2356,97 +2351,116 @@
result sign:newSign.
resultDigitByteArray := result digits.
+ lastDigit := 0.
+
%{
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;
+ 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);
- index = __MKSMALLINT(__index);
+ 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;
+ /* copy over rest */
+ __resultDigits[__index-1] = __diff;
+ index++;
+ while (__index <= __len1) {
+ __resultDigits[__index-1] = __myDigits[__index-1];
+ __index++;
+ }
+ break;
+ }
+ __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;
+ /* copy over rest */
+ __resultDigits[__index-1] = __diff;
+ index++;
+ while (__index <= __len2) {
+ __resultDigits[__index-1] = __otherDigits[__index-1];
+ __index++;
+ }
+ break;
+ } else {
+ __borrow = -1;
+ __diff += 0x100;
+ }
+ __resultDigits[__index-1] = __diff;
+ __index++;
+ }
+ }
+ }
+ borrow = __MKSMALLINT(__borrow);
+ index = __MKSMALLINT(__index);
+ lastDigit = __MKSMALLINT(__resultDigits[__index-1-1]);
}
%}.
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
- ].
+ 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.
@@ -2455,35 +2469,40 @@
"/ borrow := 0
"/ ].
- resultDigitByteArray basicAt:index put:diff.
- index := index + 1
- ].
+ 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
+ ].
+ lastDigit := resultDigitByteArray basicAt:(resultDigitByteArray size).
+ ].
+
+ (lastDigit ~~ 0) ifTrue:[
+ ^ result
].
^ result compressed
@@ -3298,5 +3317,5 @@
!LargeInteger class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.102 1999-05-19 20:13:51 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.103 1999-05-19 22:16:51 cg Exp $'
! !