--- a/LargeInteger.st Mon Sep 24 21:02:02 2007 +0200
+++ b/LargeInteger.st Tue Sep 25 15:58:09 2007 +0200
@@ -9,7 +9,6 @@
other person. No title to or ownership of the software is
hereby transferred.
"
-
"{ Package: 'stx:libbasic' }"
Integer subclass:#LargeInteger
@@ -389,47 +388,47 @@
Use a special method for this case ...
"
((numberClass := aNumber class) == SmallInteger) ifTrue:[
- sign > 0 ifTrue:[
- aNumber > 0 ifTrue:[
- ^ self absFastMinus:aNumber sign:1
- ].
- ^ self absFastPlus:aNumber sign:1
- ].
- aNumber > 0 ifTrue:[
- ^ self absFastPlus:aNumber sign:-1
- ].
- ^ self absFastMinus:aNumber sign:-1
+ sign > 0 ifTrue:[
+ aNumber > 0 ifTrue:[
+ ^ self absFastMinus:aNumber sign:1
+ ].
+ ^ self absFastPlus:aNumber sign:1
+ ].
+ aNumber > 0 ifTrue:[
+ ^ self absFastPlus:aNumber sign:-1
+ ].
+ ^ self absFastMinus:aNumber sign:-1
].
"
if the argument is not a largeInteger, coerce
"
(numberClass == self class) ifFalse:[
- ^ self retry:#- coercing:aNumber
+ ^ self retry:#- coercing:aNumber
].
otherSign := aNumber sign.
(sign > 0) ifTrue:[
- "I am positive"
- (otherSign > 0) ifTrue:[
- "+large - +large"
- ^ self absMinus:aNumber sign:1
- ].
- (otherSign < 0) ifTrue:[
- "+large - -large"
- ^ self absPlus:aNumber sign:1
- ].
- "should not happen"
- ^ self
+ "I am positive"
+ (otherSign > 0) ifTrue:[
+ "+large - +large"
+ ^ self absMinus:aNumber sign:1
+ ].
+ (otherSign < 0) ifTrue:[
+ "+large - -large"
+ ^ self absPlus:aNumber sign:1
+ ].
+ "should not happen"
+ ^ self
].
"I am negative"
(otherSign > 0) ifTrue:[
- "-large - +large"
- ^ self absPlus:aNumber sign:-1
+ "-large - +large"
+ ^ self absPlus:aNumber sign:-1
].
(otherSign < 0) ifTrue:[
- "-large - -large"
- ^ self absMinus:aNumber sign:-1
+ "-large - -large"
+ ^ self absMinus:aNumber sign:-1
].
^ self
@@ -2963,9 +2962,9 @@
len2 := otherDigitByteArray size.
len1 > len2 ifTrue:[
- lResult := len1
+ lResult := len1
] ifFalse:[
- lResult := (len1 max: len2) + 1.
+ lResult := (len1 max: len2) + 1.
].
result := self class basicNew numberOfDigits:lResult.
result sign:newSign.
@@ -2979,202 +2978,202 @@
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;
- INT __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;
+ int __len1 = __intVal(len1);
+ int __len2 = __intVal(len2);
+ int __minLen = __len1 < __len2 ? __len1 : __len2;
+ int __index, __borrow = 0;
+ INT __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;
#if defined(__LSBFIRST__)
# if __POINTER_SIZE__ == 8
- /*
- * subtract int-wise
- */
- while ((__index+3) <= __minLen) {
- /* do not make this into one expression - ask cg why */
- __diff = ((unsigned int *)(__myDigits+__index-1))[0];
- __diff -= ((unsigned int *)(__otherDigits+__index-1))[0];
- __diff -= __borrow;
-
- if (__diff >= 0) {
- __borrow = 0;
- } else {
- __borrow = 1;
- /* __diff += 0x10000; */
- }
- ((unsigned int *)(__resultDigits+__index-1))[0] = __diff;
- __index += 4;
- }
+ /*
+ * subtract int-wise
+ */
+ while ((__index+3) <= __minLen) {
+ /* do not make this into one expression - ask cg why */
+ __diff = ((unsigned int *)(__myDigits+__index-1))[0];
+ __diff -= ((unsigned int *)(__otherDigits+__index-1))[0];
+ __diff -= __borrow;
+
+ if (__diff >= 0) {
+ __borrow = 0;
+ } else {
+ __borrow = 1;
+ /* __diff += 0x10000; */
+ }
+ ((unsigned int *)(__resultDigits+__index-1))[0] = __diff;
+ __index += 4;
+ }
# endif /* 64bit */
- /*
- * subtract short-wise
- */
- while (__index < __minLen) { /* i.e. index+1 <= minLen */
- /* do not make this into one expression - ask cg why */
- __diff = ((unsigned short *)(__myDigits+__index-1))[0];
- __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- } else {
- __borrow = 1;
- /* __diff += 0x10000; */
- }
- ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
- __index += 2;
- }
-
- if (__index == __minLen) {
- /* one of the operands has odd length - cannot continue short-wise */
- } else {
- if (__len1 > __len2) {
- while (__index < __len1) {
- /* do not make this into one expression - ask cg why */
- __diff = ((unsigned short *)(__myDigits+__index-1))[0];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
- __index += 2;
-
- /* copy over rest */
- while (__index < __len1) {
- ((unsigned short *)(__resultDigits+__index-1))[0] = ((unsigned short *)(__myDigits+__index-1))[0];
- __index+=2;
- }
- if (__index <= __len1) {
- __resultDigits[__index-1] = __myDigits[__index-1];
- __index++;
- }
- break;
- }
- __borrow = 1;
- /* __diff += 0x10000; */
- ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
- __index += 2;
- }
- } else {
- if (__len2 > __len1) {
- while (__index < __len2) {
- /* do not make this into one expression - ask cg why */
- __diff = 0;
- __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- } else {
- __borrow = 1;
- /* __diff += 0x10000; */
- }
- ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
- __index += 2;
- }
- }
- }
- }
+ /*
+ * subtract short-wise
+ */
+ while (__index < __minLen) { /* i.e. index+1 <= minLen */
+ /* do not make this into one expression - ask cg why */
+ __diff = ((unsigned short *)(__myDigits+__index-1))[0];
+ __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ } else {
+ __borrow = 1;
+ /* __diff += 0x10000; */
+ }
+ ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
+ __index += 2;
+ }
+
+ if (__index == __minLen) {
+ /* one of the operands has odd length - cannot continue short-wise */
+ } else {
+ if (__len1 > __len2) {
+ while (__index < __len1) {
+ /* do not make this into one expression - ask cg why */
+ __diff = ((unsigned short *)(__myDigits+__index-1))[0];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
+ __index += 2;
+
+ /* copy over rest */
+ while (__index < __len1) {
+ ((unsigned short *)(__resultDigits+__index-1))[0] = ((unsigned short *)(__myDigits+__index-1))[0];
+ __index+=2;
+ }
+ if (__index <= __len1) {
+ __resultDigits[__index-1] = __myDigits[__index-1];
+ __index++;
+ }
+ break;
+ }
+ __borrow = 1;
+ /* __diff += 0x10000; */
+ ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
+ __index += 2;
+ }
+ } else {
+ if (__len2 > __len1) {
+ while (__index < __len2) {
+ /* do not make this into one expression - ask cg why */
+ __diff = 0;
+ __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ } else {
+ __borrow = 1;
+ /* __diff += 0x10000; */
+ }
+ ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
+ __index += 2;
+ }
+ }
+ }
+ }
#endif
- /*
- * subtract byte-wise
- */
- while (__index <= __minLen) {
- /* do not make this into one expression - ask cg why */
- __diff = __myDigits[__index-1];
- __diff -= __otherDigits[__index-1];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- } else {
- __borrow = 1;
- /* __diff += 0x100; */
- }
- __resultDigits[__index-1] = __diff;
- __index++;
- }
-
- if (__len1 > __len2) {
- while (__index <= __len1) {
- /* do not make this into one expression - ask cg why */
- __diff = __myDigits[__index-1];
- __diff -= __borrow;
- 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) {
- /* do not make this into one expression - ask cg why */
- __diff = 0;
- __diff -= __otherDigits[__index-1];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- } else {
- __borrow = 1;
- /* __diff += 0x100; */
- }
- __resultDigits[__index-1] = __diff;
- __index++;
- }
- }
- }
- borrow = __mkSmallInteger(__borrow);
- index = __mkSmallInteger(__index);
- lastDigit = __mkSmallInteger(__resultDigits[__intVal(lResult)-1]);
+ /*
+ * subtract byte-wise
+ */
+ while (__index <= __minLen) {
+ /* do not make this into one expression - ask cg why */
+ __diff = __myDigits[__index-1];
+ __diff -= __otherDigits[__index-1];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ } else {
+ __borrow = 1;
+ /* __diff += 0x100; */
+ }
+ __resultDigits[__index-1] = __diff;
+ __index++;
+ }
+
+ if (__len1 > __len2) {
+ while (__index <= __len1) {
+ /* do not make this into one expression - ask cg why */
+ __diff = __myDigits[__index-1];
+ __diff -= __borrow;
+ 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) {
+ /* do not make this into one expression - ask cg why */
+ __diff = 0;
+ __diff -= __otherDigits[__index-1];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ } else {
+ __borrow = 1;
+ /* __diff += 0x100; */
+ }
+ __resultDigits[__index-1] = __diff;
+ __index++;
+ }
+ }
+ }
+ borrow = __mkSmallInteger(__borrow);
+ index = __mkSmallInteger(__index);
+ lastDigit = __mkSmallInteger(__resultDigits[__intVal(lResult)-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.
@@ -3183,40 +3182,40 @@
"/ borrow := 0
"/ ].
- resultDigitByteArray basicAt:index put:diff.
- index := index + 1
- ].
- lastDigit := resultDigitByteArray basicAt:lResult.
+ resultDigitByteArray basicAt:index put:diff.
+ index := index + 1
+ ].
+ lastDigit := resultDigitByteArray basicAt:lResult.
].
(borrow ~~ 0) ifTrue:[
- "/ must generate 255's complement
-
- result sign:-1.
- [index <= lResult] whileTrue:[
- resultDigitByteArray basicAt:index put:16rFF.
- index := index + 1.
- ].
- index := lResult.
- [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:lResult.
+ "/ must generate 255's complement
+
+ result sign:newSign negated.
+ [index <= lResult] whileTrue:[
+ resultDigitByteArray basicAt:index put:16rFF.
+ index := index + 1.
+ ].
+ index := lResult.
+ [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:lResult.
].
(lastDigit ~~ 0 and:[lResult > SmallInteger maxBytes]) ifTrue:[
- ^ result
+ ^ result
].
^ result compressed
@@ -4577,5 +4576,5 @@
!LargeInteger class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.185 2007-01-19 00:03:12 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.186 2007-09-25 13:58:09 sr Exp $'
! !