--- a/LargeInt.st Sat May 08 20:14:17 1999 +0200
+++ b/LargeInt.st Sun May 09 00:55:44 1999 +0200
@@ -234,9 +234,9 @@
"create and return a new LargeInteger with value taken from
the argument, aSmallInteger.
Notice:
- this should be only used internally, since such small
- largeIntegers do not normally occur in the system.
- (They are used by myself)
+ this should be only used internally, since such small
+ largeIntegers do not normally occur in the system.
+ (They are used by myself)
May change/be removed without notice."
^ self basicNew value:aSmallInteger
@@ -421,33 +421,33 @@
Use a special method for this case ...
"
(cls == SmallInteger) ifTrue:[
- abs := aNumber.
- abs := abs abs.
- (abs between:1 and:16r00ffffff) ifTrue:[
- divMod := self absFastDivMod:abs.
- ] ifFalse:[
- n := abs asLargeInteger.
- ].
+ abs := aNumber.
+ abs := abs abs.
+ (abs between:1 and:16r00ffffff) ifTrue:[
+ divMod := self absFastDivMod:abs.
+ ] ifFalse:[
+ n := abs asLargeInteger.
+ ].
] ifFalse:[
- "
- if the argument is not a largeInteger, coerce
- "
- (cls == self class) ifFalse:[
- ^ self retry:#// coercing:aNumber
- ].
- n := aNumber
+ "
+ if the argument is not a largeInteger, coerce
+ "
+ (cls == self class) ifFalse:[
+ ^ self retry:#// coercing:aNumber
+ ].
+ n := aNumber
].
divMod isNil ifTrue:[
- divMod := self absDivMod:n.
+ divMod := self absDivMod:n.
].
quo := divMod at:1.
(sign == aNumber sign) ifFalse:[
- "/ adjust for truncation if negative and there is a remainder ...
- quo := quo sign:-1.
- (divMod at:2) == 0 ifFalse:[
- ^ quo - 1
- ].
+ "/ adjust for truncation if negative and there is a remainder ...
+ quo := quo sign:-1.
+ (divMod at:2) == 0 ifFalse:[
+ ^ quo - 1
+ ].
].
^ quo
@@ -485,11 +485,11 @@
|abs rem negativeDivisor|
aNumber negative ifTrue:[
- negativeDivisor := true.
- abs := aNumber negated.
+ negativeDivisor := true.
+ abs := aNumber negated.
] ifFalse:[
- negativeDivisor := false.
- abs := aNumber.
+ negativeDivisor := false.
+ abs := aNumber.
].
"
@@ -497,33 +497,33 @@
Use a special method for this case ...
"
(aNumber class == SmallInteger) ifTrue:[
- (abs between:1 and:16r00ffffff) ifTrue:[
- rem := (self absFastDivMod:abs) at:2.
- ] ifFalse:[
- rem := self absMod:abs asLargeInteger
- ].
+ (abs between:1 and:16r00ffffff) ifTrue:[
+ rem := (self absFastDivMod:abs) at:2.
+ ] ifFalse:[
+ rem := self absMod:abs asLargeInteger
+ ].
] ifFalse:[
- "
- if the argument is not a largeInteger, coerce
- "
- (aNumber class == self class) ifFalse:[
- ^ self retry:#\\ coercing:aNumber
- ].
-
- rem := self absMod:abs.
+ "
+ if the argument is not a largeInteger, coerce
+ "
+ (aNumber class == self class) ifFalse:[
+ ^ self retry:#\\ coercing:aNumber
+ ].
+
+ rem := self absMod:abs.
].
rem = 0 ifFalse:[
- negativeDivisor ifTrue:[
- rem := rem sign:-1
- ].
- (self negative ~~ negativeDivisor) ifTrue:[
- "different sign, so remainder would have been negative.
- rem has been rounded toward zero, this code will simulate
- rounding to negative infinity."
-
- rem := aNumber - rem.
- ].
+ negativeDivisor ifTrue:[
+ rem := rem sign:-1
+ ].
+ (self negative ~~ negativeDivisor) ifTrue:[
+ "different sign, so remainder would have been negative.
+ rem has been rounded toward zero, this code will simulate
+ rounding to negative infinity."
+
+ rem := aNumber - rem.
+ ].
].
^ rem
@@ -567,19 +567,19 @@
cls := aNumber class.
(cls == SmallInteger) ifTrue:[
- "
- this is the common case, dividing by a SmallInteger.
- Use a special method for this case ...
- "
- (aNumber between:1 and:16r00ffffff) ifTrue:[
- ^ self absFastDivMod:aNumber abs.
- ].
- n := aNumber asLargeInteger.
+ "
+ this is the common case, dividing by a SmallInteger.
+ Use a special method for this case ...
+ "
+ (aNumber between:1 and:16r00ffffff) ifTrue:[
+ ^ self absFastDivMod:aNumber abs.
+ ].
+ n := aNumber asLargeInteger.
] ifFalse:[
- (cls == self class) ifFalse:[
- ^ super divMod:aNumber
- ].
- n := aNumber.
+ (cls == self class) ifFalse:[
+ ^ super divMod:aNumber
+ ].
+ n := aNumber.
].
^ self absDivMod:n abs
@@ -676,26 +676,26 @@
Use a special method for this case ...
"
(aNumber class == SmallInteger) ifTrue:[
- abs := aNumber.
- abs := abs abs.
- (abs between:1 and:16r00ffffff) ifTrue:[
- quo := (self absFastDivMod:abs) at:1.
- (sign == otherSign) ifTrue:[^ quo].
- ^ quo sign:-1
- ]
+ abs := aNumber.
+ abs := abs abs.
+ (abs between:1 and:16r00ffffff) ifTrue:[
+ quo := (self absFastDivMod:abs) at:1.
+ (sign == otherSign) ifTrue:[^ quo].
+ ^ quo sign:-1
+ ]
].
"
if the argument is not a largeInteger, coerce
"
(aNumber class == self class) ifFalse:[
- ^ self retry:#quo: coercing:aNumber
+ ^ self retry:#quo: coercing:aNumber
].
sign < 0 ifTrue:[
- (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber negated) at:1].
+ (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber negated) at:1].
] ifFalse:[
- (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber) at:1].
+ (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber) at:1].
].
^ ((self absDivMod:aNumber) at:1) sign:-1
@@ -736,26 +736,26 @@
Use special code for this case ...
"
(aNumber class == SmallInteger) ifTrue:[
- abs := aNumber.
- abs := abs abs.
- (abs between:1 and:16r00ffffff) ifTrue:[
- rem := (self absFastDivMod:abs) at:2.
- ] ifFalse:[
- rem := self absMod:abs asLargeInteger
- ].
+ abs := aNumber.
+ abs := abs abs.
+ (abs between:1 and:16r00ffffff) ifTrue:[
+ rem := (self absFastDivMod:abs) at:2.
+ ] ifFalse:[
+ rem := self absMod:abs asLargeInteger
+ ].
] ifFalse:[
- "
- if the argument is not a largeInteger, coerce
- "
- (aNumber class == self class) ifFalse:[
- ^ self retry:#rem coercing:aNumber
- ].
-
- rem := self absMod:aNumber
+ "
+ if the argument is not a largeInteger, coerce
+ "
+ (aNumber class == self class) ifFalse:[
+ ^ self retry:#rem coercing:aNumber
+ ].
+
+ rem := self absMod:aNumber
].
sign < 0 ifTrue:[
- ^ rem sign:-1
+ ^ rem sign:-1
].
^ rem
@@ -847,10 +847,10 @@
|t digits|
sign < 0 ifFalse:[
- index > digitByteArray size ifTrue:[
- ^ 0
- ].
- ^ digitByteArray at:index.
+ index > digitByteArray size ifTrue:[
+ ^ 0
+ ].
+ ^ digitByteArray at:index.
].
"/ negative int - do 2's complement here
@@ -858,7 +858,7 @@
t sign:1.
digits := t digits.
index > digits size ifTrue:[
- ^ 16rFF
+ ^ 16rFF
].
^ digits at:index.
@@ -1271,7 +1271,7 @@
"/ speed up compare to 0
(aNumber == 0 and:[sign == 0]) ifTrue:[
- ^ true
+ ^ true
].
(aNumber class == self class) ifFalse:[
@@ -1668,22 +1668,22 @@
shift "{ Class: SmallInteger }" |
anInteger == 0 ifTrue:[
- ^ DivisionByZeroSignal raise
+ ^ DivisionByZeroSignal raise
].
self = anInteger ifTrue:[
- ^ Array with:1 with:0
+ ^ Array with:1 with:0
].
shift := self highBit - anInteger highBit.
dividend := self simpleDeepCopy sign:1.
shift < 0 ifTrue:[
- ^ Array with:0 with:dividend.
+ ^ Array with:0 with:dividend.
].
shift == 0 ifTrue:[
- divisor := anInteger simpleDeepCopy.
+ divisor := anInteger simpleDeepCopy.
] ifFalse:[
- divisor := anInteger bitShift:shift.
+ divisor := anInteger bitShift:shift.
].
quo := self class basicNew numberOfDigits:((shift // 8) + 1).
@@ -1691,14 +1691,14 @@
shift := shift + 1.
[shift > 0] whileTrue:[
- (dividend absLess:divisor) ifFalse:[
- digits bitSetAt:shift.
- (dividend absSubtract: divisor) ifFalse:[ "result == 0"
- ^ Array with:quo compressed with:dividend compressed
- ].
- ].
- shift := shift - 1.
- divisor div2.
+ (dividend absLess:divisor) ifFalse:[
+ digits bitSetAt:shift.
+ (dividend absSubtract: divisor) ifFalse:[ "result == 0"
+ ^ Array with:quo compressed with:dividend compressed
+ ].
+ ].
+ shift := shift - 1.
+ divisor div2.
].
^ Array with:quo compressed with:dividend compressed
@@ -1733,17 +1733,17 @@
"/ numbers to be compared ...
[(digitByteArray basicAt:len1) == 0] whileTrue:[
- len1 := len1 - 1
+ len1 := len1 - 1
].
[(otherDigitByteArray basicAt:len2) == 0] whileTrue:[
- len2 := len2 - 1
+ len2 := len2 - 1
].
(len1 ~~ len2) ifTrue:[^ false].
[len1 > 0] whileTrue:[
- d1 := digitByteArray basicAt:len1.
- d2 := otherDigitByteArray basicAt:len1.
- (d1 ~~ d2) ifTrue:[^ false].
- len1 := len1 - 1
+ d1 := digitByteArray basicAt:len1.
+ d2 := otherDigitByteArray basicAt:len1.
+ (d1 ~~ d2) ifTrue:[^ false].
+ len1 := len1 - 1
].
^ true
@@ -1761,12 +1761,12 @@
ok|
aPositiveSmallInteger == 0 ifTrue:[
- ^ DivisionByZeroSignal raise
+ ^ DivisionByZeroSignal raise
].
"This cannot happen (if always normalized)
self < aPositiveSmallInteger ifTrue:[
- ^ Array with:0 with:self
+ ^ Array with:0 with:self
].
"
count := digitByteArray size.
@@ -1781,67 +1781,67 @@
if (__isByteArray(__digits)
&& __isByteArray(newDigitByteArray)
&& __bothSmallInteger(count, aPositiveSmallInteger)) {
- unsigned INT rest = 0;
- int index = __intVal(count);
- int index0;
- unsigned INT divisor = __intVal(aPositiveSmallInteger);
- unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element;
- unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element;
-
- index0 = index - 1;
+ unsigned INT rest = 0;
+ int index = __intVal(count);
+ int index0;
+ unsigned INT divisor = __intVal(aPositiveSmallInteger);
+ unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element;
+ unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element;
+
+ index0 = index - 1;
#ifdef i386
- if (divisor <= 0xFFFF) {
- if ((index & 1) == 0) { /* even number of bytes */
- while (index > 1) {
- unsigned INT t;
- unsigned INT div;
+ if (divisor <= 0xFFFF) {
+ if ((index & 1) == 0) { /* even number of bytes */
+ while (index > 1) {
+ unsigned INT t;
+ unsigned INT div;
# ifdef i386 /* LSB_FIRST */
- index -= 2;
- t = *((unsigned short *)(&digitBytes[index]));
+ index -= 2;
+ t = *((unsigned short *)(&digitBytes[index]));
# else
- index--;
- t = digitBytes[index];
- index--;
- t = (t << 8) | digitBytes[index];
+ index--;
+ t = digitBytes[index];
+ index--;
+ t = (t << 8) | digitBytes[index];
# endif
- t = t | (rest << 16);
- div = t / divisor;
- rest = t % divisor;
+ t = t | (rest << 16);
+ div = t / divisor;
+ rest = t % divisor;
# ifdef i386 /* LSB_FIRST */
- *((unsigned short *)(&resultBytes[index])) = (div & 0xFFFF);
+ *((unsigned short *)(&resultBytes[index])) = (div & 0xFFFF);
# else
- resultBytes[index+1] = (div >> 8);
- resultBytes[index] = (div & 0xFF);
+ resultBytes[index+1] = (div >> 8);
+ resultBytes[index] = (div & 0xFF);
# endif
- }
- }
- }
+ }
+ }
+ }
#endif
- while (index > 0) {
- unsigned INT t;
-
- index--;
- t = digitBytes[index];
- t = t | (rest << 8);
- resultBytes[index] = t / divisor;
- rest = t % divisor;
- }
- prevRest = __MKSMALLINT(rest);
- ok = true;
-
- /*
- * no need to normalize ?
- */
- while ((index0 > sizeof(INT)) && (resultBytes[index0]==0)) {
- index0--;
- }
-
- if ((index0 > sizeof(INT))
- && (resultBytes[index0-1])) {
- RETURN ( __ARRAY_WITH2(result, prevRest));
- }
+ while (index > 0) {
+ unsigned INT t;
+
+ index--;
+ t = digitBytes[index];
+ t = t | (rest << 8);
+ resultBytes[index] = t / divisor;
+ rest = t % divisor;
+ }
+ prevRest = __MKSMALLINT(rest);
+ ok = true;
+
+ /*
+ * no need to normalize ?
+ */
+ while ((index0 > sizeof(INT)) && (resultBytes[index0]==0)) {
+ index0--;
+ }
+
+ if ((index0 > sizeof(INT))
+ && (resultBytes[index0-1])) {
+ RETURN ( __ARRAY_WITH2(result, prevRest));
+ }
}
%}.
"
@@ -1849,7 +1849,7 @@
(could also do a primitiveFailure here)
"
ok ifFalse:[
- self primitiveFailed
+ self primitiveFailed
].
^ Array with:(result compressed) with:prevRest
@@ -1943,7 +1943,7 @@
((aSmallInteger < (SmallInteger minVal + 255))
or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
- ^ self absPlus:(LargeInteger value:aSmallInteger).
+ ^ self absPlus:(LargeInteger value:aSmallInteger).
].
len := digitByteArray size.
@@ -1956,63 +1956,63 @@
if (__isByteArray(__INST(digitByteArray))
&& __isByteArray(resultDigitByteArray)
&& __isSmallInteger(aSmallInteger)) {
- 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 __lastDigit = 0;
-
- if (__carry < 0) {
- __carry = -__carry;
- }
-
- while (__carry) {
- if (__index <= __len) {
- __carry += __src[__index-1];
- }
- __dst[__index-1] = __lastDigit = __carry & 0xFF;
- __carry >>= 8;
- __index++;
- }
- if (__index <= __intVal(rsltLen)) {
- while (__index <= __len) {
- __dst[__index-1] = __src[__index-1];
- __index++;
- }
- __lastDigit = 0;
- }
- if (lastDigit) {
- RETURN (result);
- }
- ok = true;
+ 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 __lastDigit = 0;
+
+ if (__carry < 0) {
+ __carry = -__carry;
+ }
+
+ while (__carry) {
+ if (__index <= __len) {
+ __carry += __src[__index-1];
+ }
+ __dst[__index-1] = __lastDigit = __carry & 0xFF;
+ __carry >>= 8;
+ __index++;
+ }
+ if (__index <= __intVal(rsltLen)) {
+ while (__index <= __len) {
+ __dst[__index-1] = __src[__index-1];
+ __index++;
+ }
+ __lastDigit = 0;
+ }
+ if (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
@@ -2040,22 +2040,22 @@
"/ numbers to be compared ...
[myLen > 0 and:[(digitByteArray basicAt:myLen) == 0]] whileTrue:[
- myLen := myLen - 1
+ myLen := myLen - 1
].
[otherLen > 0 and:[(otherDigitByteArray basicAt:otherLen) == 0]] whileTrue:[
- otherLen := otherLen - 1
+ otherLen := otherLen - 1
].
(myLen < otherLen) ifTrue:[^ true].
(myLen > otherLen) ifTrue:[^ false].
[myLen > 0] whileTrue:[
- d1 := digitByteArray basicAt:myLen.
- d2 := otherDigitByteArray basicAt:myLen.
- d1 == d2 ifFalse:[
- (d1 < d2) ifTrue:[^ true].
- ^ false
- ].
- myLen := myLen - 1
+ d1 := digitByteArray basicAt:myLen.
+ d2 := otherDigitByteArray basicAt:myLen.
+ d1 == d2 ifFalse:[
+ (d1 < d2) ifTrue:[^ true].
+ ^ false
+ ].
+ myLen := myLen - 1
].
^ false
@@ -2083,22 +2083,22 @@
"/ numbers to be compared ...
[(digitByteArray basicAt:myLen) == 0] whileTrue:[
- myLen := myLen - 1
+ myLen := myLen - 1
].
[(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[
- otherLen := otherLen - 1
+ otherLen := otherLen - 1
].
(myLen < otherLen) ifTrue:[^ true].
(myLen > otherLen) ifTrue:[^ false].
[myLen > 0] whileTrue:[
- d1 := digitByteArray basicAt:myLen.
- d2 := otherDigitByteArray basicAt:myLen.
- d1 == d2 ifFalse:[
- (d1 < d2) ifTrue:[^ true].
- ^ false.
- ].
- myLen := myLen - 1
+ d1 := digitByteArray basicAt:myLen.
+ d2 := otherDigitByteArray basicAt:myLen.
+ d1 == d2 ifFalse:[
+ (d1 < d2) ifTrue:[^ true].
+ ^ false.
+ ].
+ myLen := myLen - 1
].
^ true
@@ -2209,34 +2209,34 @@
shift "{ Class: SmallInteger }" |
anInteger == 0 ifTrue:[
- ^ DivisionByZeroSignal raise
+ ^ DivisionByZeroSignal raise
].
self = anInteger ifTrue:[
- ^ 0
+ ^ 0
].
shift := self highBit - anInteger highBit.
dividend := self simpleDeepCopy sign:1.
shift < 0 ifTrue:[
- ^ dividend.
+ ^ dividend.
].
shift == 0 ifTrue:[
- divisor := anInteger simpleDeepCopy.
+ divisor := anInteger simpleDeepCopy.
] ifFalse:[
- divisor := anInteger bitShift:shift.
+ divisor := anInteger bitShift:shift.
].
shift := shift + 1.
[shift > 0] whileTrue:[
- (dividend absLess:divisor) ifFalse:[
- (dividend absSubtract: divisor) ifFalse:[ "result == 0"
- ^ dividend compressed
- ].
- ].
- shift := shift - 1.
- divisor div2.
+ (dividend absLess:divisor) ifFalse:[
+ (dividend absSubtract: divisor) ifFalse:[ "result == 0"
+ ^ dividend compressed
+ ].
+ ].
+ shift := shift - 1.
+ divisor div2.
].
^ dividend compressed
@@ -2277,56 +2277,63 @@
&& __isByteArray(otherDigitByteArray)
&& __isByteArray(resultDigitByteArray)
&& __bothSmallInteger(len1, len2)) {
- unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
- unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
- unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
- unsigned char *_p1, *_p2, *_pResult, *_pResult1;
- unsigned INT _v;
- int _len1 = __intVal(len1);
- int _len2 = __intVal(len2);
-
- /*
- * the code below is a q&d hack - it certainly needs some more thought,
- * if large numbers are multiplied often ...
- */
- for (_p1 = myBytes; _p1 < myBytes + _len1; _p1++) {
- _pResult = resultBytes + (_p1 - myBytes);
- for (_p2 = otherBytes; _p2 < otherBytes + _len2; _p2++) {
- _v = ((*_p1) * (*_p2)) + *_pResult;
- *_pResult = _v & 0xFF;
- _v >>= 8; /* now _v contains the carry*/
- _pResult++;
- if (_v) {
- for (_pResult1 = _pResult; _v; _pResult1++) {
- _v += *_pResult1;
- *_pResult1 = _v & 0xFF;
- _v >>= 8;
- }
- }
- }
- }
- ok = true;
+ unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
+ unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+ unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+ unsigned char *_p1, *_p2, *_pResult, *_pResult0, *_pResult1, *_p1Last, *_p2Last;
+ unsigned INT _v;
+ int _len1 = __intVal(len1);
+ int _len2 = __intVal(len2);
+
+ /*
+ * the code below is a q&d hack - it certainly needs some more thought,
+ * if large numbers are multiplied often ...
+ */
+ _p1Last = myBytes + _len1 - 1; /* the last byte */
+ _p2Last = otherBytes + _len2 - 1; /* the last byte */
+ _pResult0 = resultBytes;
+ for (_p1 = myBytes; _p1 <= _p1Last; _p1++, _pResult0++) {
+ unsigned int byte1 = *_p1;
+
+ _pResult = _pResult0;
+ _p2 = otherBytes;
+ while (_p2 <= _p2Last) {
+ _v = (byte1 * _p2[0]) + _pResult[0];
+ _pResult[0] = _v & 0xFF;
+ _v >>= 8; /* now _v contains the carry*/
+ _pResult++;
+ if (_v) {
+ for (_pResult1 = _pResult; _v; _pResult1++) {
+ _v += _pResult1[0];
+ _pResult1[0] = _v & 0xFF;
+ _v >>= 8;
+ }
+ }
+ _p2 ++;
+ }
+ }
+ ok = true;
}
%}.
ok ifFalse:[
- 1 to:len1 do:[:index1 |
- 1 to:len2 do:[:index2 |
- dstIndex := index1 + index2 - 1.
- prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
- prod := prod + (resultDigitByteArray basicAt:dstIndex).
- resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
- carry := prod bitShift:-8.
- carry ~~ 0 ifTrue:[
- idx := dstIndex + 1.
- [carry ~~ 0] whileTrue:[
- v := (resultDigitByteArray basicAt:idx) + carry.
- resultDigitByteArray basicAt:idx put:(v bitAnd:255).
- carry := v bitShift:-8.
- idx := idx + 1
- ]
- ]
- ]
- ].
+ 1 to:len1 do:[:index1 |
+ 1 to:len2 do:[:index2 |
+ dstIndex := index1 + index2 - 1.
+ prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
+ prod := prod + (resultDigitByteArray basicAt:dstIndex).
+ resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
+ carry := prod bitShift:-8.
+ carry ~~ 0 ifTrue:[
+ idx := dstIndex + 1.
+ [carry ~~ 0] whileTrue:[
+ v := (resultDigitByteArray basicAt:idx) + carry.
+ resultDigitByteArray basicAt:idx put:(v bitAnd:255).
+ carry := v bitShift:-8.
+ idx := idx + 1
+ ]
+ ]
+ ]
+ ].
].
^ result compressed
!
@@ -2349,200 +2356,200 @@
if (__isByteArray(_digitByteArray)
&& __isByteArray(otherDigitByteArray)) {
- int _len1, _len2, _newLen;
- unsigned char *_myDigits, *_otherDigits, *_newDigits;
- int _index, _carry;
- int _comLen;
-
- _len1 = __byteArraySize(_digitByteArray);
- _len2 = __byteArraySize(otherDigitByteArray);
-
- _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
- _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
-
- if (_len1 < _len2) {
- _comLen = _len1;
- _newLen = _len2;
- if (_otherDigits[_len2 - 1] == 0xFF) _newLen++;
- } else if (_len2 < _len1) {
- _comLen = _len2;
- _newLen = _len1;
- if (_myDigits[_len1 - 1] == 0xFF) _newLen++;
- } else {
- /*
- * there can only be an overflow from the high bytes,
- * if their sum is >= 255
- */
- _newLen = _len1;
- if ((_otherDigits[_len2 - 1] + _myDigits[_len1 - 1]) >= 0xFF) {
- _newLen++;
- } else {
+ int _len1, _len2, _newLen;
+ unsigned char *_myDigits, *_otherDigits, *_newDigits;
+ int _index, _carry;
+ int _comLen;
+
+ _len1 = __byteArraySize(_digitByteArray);
+ _len2 = __byteArraySize(otherDigitByteArray);
+
+ _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+ _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+
+ if (_len1 < _len2) {
+ _comLen = _len1;
+ _newLen = _len2;
+ if (_otherDigits[_len2 - 1] == 0xFF) _newLen++;
+ } else if (_len2 < _len1) {
+ _comLen = _len2;
+ _newLen = _len1;
+ if (_myDigits[_len1 - 1] == 0xFF) _newLen++;
+ } else {
+ /*
+ * there can only be an overflow from the high bytes,
+ * if their sum is >= 255
+ */
+ _newLen = _len1;
+ if ((_otherDigits[_len2 - 1] + _myDigits[_len1 - 1]) >= 0xFF) {
+ _newLen++;
+ } else {
#if defined(i386) || defined(alpha) /* actually: LSB_FIRST */
- if (_newLen == sizeof(INT)) {
- /*
- * two 32bit numbers, no carry - a very common case ...
- */
- unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits;
- RETURN (__MKULARGEINT(_sum));
- }
+ if (_newLen == sizeof(INT)) {
+ /*
+ * two 32bit numbers, no carry - a very common case ...
+ */
+ unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits;
+ RETURN (__MKULARGEINT(_sum));
+ }
#endif /* not LSB_FIRST */
- }
- _comLen = _len1;
- }
- resultDigitByteArray = __BYTEARRAY_UNINITIALIZED_NEW_INT(_newLen);
-
- /*
- * must refetch - GC could have been invoked
- */
- _digitByteArray = __INST(digitByteArray);
-
- _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
- _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
- _newDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
-
- /*
- * add them ...
- */
- _index = 1;
- _carry = 0;
+ }
+ _comLen = _len1;
+ }
+ resultDigitByteArray = __BYTEARRAY_UNINITIALIZED_NEW_INT(_newLen);
+
+ /*
+ * must refetch - GC could have been invoked
+ */
+ _digitByteArray = __INST(digitByteArray);
+
+ _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+ _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+ _newDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+
+ /*
+ * add them ...
+ */
+ _index = 1;
+ _carry = 0;
#if defined(i386) || defined(alpha) /* actually: LSB first */
# ifdef INT64
- /*
- * have a 64bit integer type;
- * add long-wise
- */
- while (_index < _comLen) {
- UINT64 _sum;
-
- _sum = _carry;
- _sum += *(unsigned *)(&(_myDigits[_index - 1]));
- _sum += *(unsigned *)(&(_otherDigits[_index - 1]));
- _carry = _sum >> 32;
- _sum = _sum & 0xFFFFFFFF;
- *(unsigned *)(&(_newDigits[_index - 1])) = _sum;
- _index += 4;
- }
+ /*
+ * have a 64bit integer type;
+ * add long-wise
+ */
+ while (_index < _comLen) {
+ UINT64 _sum;
+
+ _sum = _carry;
+ _sum += *(unsigned *)(&(_myDigits[_index - 1]));
+ _sum += *(unsigned *)(&(_otherDigits[_index - 1]));
+ _carry = _sum >> 32;
+ _sum = _sum & 0xFFFFFFFF;
+ *(unsigned *)(&(_newDigits[_index - 1])) = _sum;
+ _index += 4;
+ }
# endif
- /*
- * add short-wise
- */
- while (_index < _comLen) {
- unsigned int _sum;
-
- _sum = _carry;
- _sum += *(unsigned short *)(&(_myDigits[_index - 1]));
- _sum += *(unsigned short *)(&(_otherDigits[_index - 1]));
- _carry = _sum >> 16;
- _sum = _sum & 0xFFFF;
- *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
- _index += 2;
- }
+ /*
+ * add short-wise
+ */
+ while (_index < _comLen) {
+ unsigned int _sum;
+
+ _sum = _carry;
+ _sum += *(unsigned short *)(&(_myDigits[_index - 1]));
+ _sum += *(unsigned short *)(&(_otherDigits[_index - 1]));
+ _carry = _sum >> 16;
+ _sum = _sum & 0xFFFF;
+ *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
+ _index += 2;
+ }
#endif
- /*
- * add byte
- */
- while (_index <= _comLen) {
- unsigned int _sum;
-
- _sum = _carry;
- _sum += _myDigits[_index - 1];
- _sum += _otherDigits[_index - 1];
- _carry = _sum >> 8;
- _sum = _sum & 0xFF;
- _newDigits[_index - 1] = _sum;
- _index++;
- }
-
- /*
- * rest
- */
- while (_index <= _newLen) {
- unsigned int _sum;
-
- _sum = _carry;
- if (_index <= _len1) {
- _sum += _myDigits[_index - 1];
- if (_index <= _len2) {
- _sum += _otherDigits[_index - 1];
- }
- } else {
- if (_index <= _len2) {
- _sum += _otherDigits[_index - 1];
- }
- }
- _carry = _sum >> 8;
- _sum = _sum & 0xFF;
- _newDigits[_index - 1] = _sum;
- _index++;
- }
+ /*
+ * add byte
+ */
+ while (_index <= _comLen) {
+ unsigned int _sum;
+
+ _sum = _carry;
+ _sum += _myDigits[_index - 1];
+ _sum += _otherDigits[_index - 1];
+ _carry = _sum >> 8;
+ _sum = _sum & 0xFF;
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
+
+ /*
+ * rest
+ */
+ while (_index <= _newLen) {
+ unsigned int _sum;
+
+ _sum = _carry;
+ if (_index <= _len1) {
+ _sum += _myDigits[_index - 1];
+ if (_index <= _len2) {
+ _sum += _otherDigits[_index - 1];
+ }
+ } else {
+ if (_index <= _len2) {
+ _sum += _otherDigits[_index - 1];
+ }
+ }
+ _carry = _sum >> 8;
+ _sum = _sum & 0xFF;
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
}
%}.
resultDigitByteArray notNil ifTrue:[
- result := self class basicNew.
- result setDigits:resultDigitByteArray.
+ result := self class basicNew.
+ result setDigits:resultDigitByteArray.
] ifFalse:[
- len1 := digitByteArray size.
- len2 := otherDigitByteArray size.
-
- "/ earlier versions estimated the newLength as:
- "/ (len1 max:len2) + 1
- "/ and reduced the result.
- "/ however, if one of the addends is smaller,
- "/ the result will never require another digit,
- "/ if the highest digit of the larger addent is
- "/ not equal to 255. Therefore, in most cases,
- "/ we can avoid the computation and resizing
- "/ in #reduced.
-
- len1 < len2 ifTrue:[
- newLen := len2.
- (otherDigitByteArray at:len2) == 16rFF ifTrue:[
- newLen := newLen + 1
- ]
- ] ifFalse:[
- len2 < len1 ifTrue:[
- newLen := len1.
- (digitByteArray at:len1) == 16rFF ifTrue:[
- newLen := newLen + 1
- ]
- ] ifFalse:[
- newLen := len1 + 1.
- ]
- ].
-
- result := self class basicNew numberOfDigits:newLen.
- resultDigitByteArray := result digits.
-
- index := 1.
- carry := 0.
-
- done := false.
- [done] whileFalse:[
- sum := carry.
- (index <= len1) ifTrue:[
- sum := sum + (digitByteArray basicAt:index).
- (index <= len2) ifTrue:[
- sum := sum + (otherDigitByteArray basicAt:index)
- ]
- ] ifFalse:[
- (index <= len2) ifTrue:[
- sum := sum + (otherDigitByteArray basicAt:index)
- ] ifFalse:[
- "end reached"
- done := true
- ]
- ].
- (sum >= 16r100) ifTrue:[
- carry := 1.
- sum := sum - 16r100
- ] ifFalse:[
- carry := 0
- ].
- resultDigitByteArray basicAt:index put:sum.
- index := index + 1
- ].
+ len1 := digitByteArray size.
+ len2 := otherDigitByteArray size.
+
+ "/ earlier versions estimated the newLength as:
+ "/ (len1 max:len2) + 1
+ "/ and reduced the result.
+ "/ however, if one of the addends is smaller,
+ "/ the result will never require another digit,
+ "/ if the highest digit of the larger addent is
+ "/ not equal to 255. Therefore, in most cases,
+ "/ we can avoid the computation and resizing
+ "/ in #reduced.
+
+ len1 < len2 ifTrue:[
+ newLen := len2.
+ (otherDigitByteArray at:len2) == 16rFF ifTrue:[
+ newLen := newLen + 1
+ ]
+ ] ifFalse:[
+ len2 < len1 ifTrue:[
+ newLen := len1.
+ (digitByteArray at:len1) == 16rFF ifTrue:[
+ newLen := newLen + 1
+ ]
+ ] ifFalse:[
+ newLen := len1 + 1.
+ ]
+ ].
+
+ result := self class basicNew numberOfDigits:newLen.
+ resultDigitByteArray := result digits.
+
+ index := 1.
+ carry := 0.
+
+ done := false.
+ [done] whileFalse:[
+ sum := carry.
+ (index <= len1) ifTrue:[
+ sum := sum + (digitByteArray basicAt:index).
+ (index <= len2) ifTrue:[
+ sum := sum + (otherDigitByteArray basicAt:index)
+ ]
+ ] ifFalse:[
+ (index <= len2) ifTrue:[
+ sum := sum + (otherDigitByteArray basicAt:index)
+ ] ifFalse:[
+ "end reached"
+ done := true
+ ]
+ ].
+ (sum >= 16r100) ifTrue:[
+ carry := 1.
+ sum := sum - 16r100
+ ] ifFalse:[
+ carry := 0
+ ].
+ resultDigitByteArray basicAt:index put:sum.
+ index := index + 1
+ ].
].
^ result compressed
@@ -2571,12 +2578,12 @@
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.
@@ -2584,26 +2591,26 @@
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
+ 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
@@ -2622,66 +2629,66 @@
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(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
@@ -2707,57 +2714,57 @@
b := digitByteArray at:nBytes.
(b bitAnd:16r80) ~~ 0 ifTrue:[
- "/ need another byte
- nBytes := nBytes + 1.
- t := ByteArray uninitializedNew:nBytes.
- t replaceFrom:1 to:nBytes-1 with:digitByteArray startingAt:1.
- t at:nBytes put:0.
- digitByteArray := t.
+ "/ need another byte
+ nBytes := nBytes + 1.
+ t := ByteArray uninitializedNew:nBytes.
+ t replaceFrom:1 to:nBytes-1 with:digitByteArray startingAt:1.
+ t at:nBytes put:0.
+ digitByteArray := t.
].
%{
OBJ __digits = __INST(digitByteArray);
if (__isByteArray(__digits)) {
- int __nBytes = __intVal(nBytes);
- unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
- unsigned INT __carry = 0, __newCarry, __this;
- int __idx;
+ int __nBytes = __intVal(nBytes);
+ unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
+ unsigned INT __carry = 0, __newCarry, __this;
+ int __idx;
#if defined(alpha64)
- if (sizeof(unsigned INT) == 8) {
- while (__nBytes >= 8) {
- __this = ((unsigned INT *)__bp)[0];
- __newCarry = (__this >> 63) /* & 1 */;
- ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
- __carry = __newCarry;
- __bp += 8;
- __nBytes -= 8;
- }
- }
+ if (sizeof(unsigned INT) == 8) {
+ while (__nBytes >= 8) {
+ __this = ((unsigned INT *)__bp)[0];
+ __newCarry = (__this >> 63) /* & 1 */;
+ ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp += 8;
+ __nBytes -= 8;
+ }
+ }
#else
# if defined(i386) /* XXX actually: LSB_FIRST */
- if (sizeof(unsigned INT) == 4) {
- while (__nBytes >= 4) {
- __this = ((unsigned INT *)__bp)[0];
- __newCarry = (__this >> 31) /* & 1 */;
- ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
- __carry = __newCarry;
- __bp += 4;
- __nBytes -= 4;
- }
- }
+ if (sizeof(unsigned INT) == 4) {
+ while (__nBytes >= 4) {
+ __this = ((unsigned INT *)__bp)[0];
+ __newCarry = (__this >> 31) /* & 1 */;
+ ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp += 4;
+ __nBytes -= 4;
+ }
+ }
# endif
#endif
- while (__nBytes) {
- __this = __bp[0];
- __newCarry = (__this >> 7) /* & 1 */;
- __bp[0] = (__this << 1) | __carry;
- __carry = __newCarry;
- __bp++;
- __nBytes--;
- }
- RETURN (self);
+ while (__nBytes) {
+ __this = __bp[0];
+ __newCarry = (__this >> 7) /* & 1 */;
+ __bp[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp++;
+ __nBytes--;
+ }
+ RETURN (self);
}
%}.
self primitiveFailed
@@ -2844,5 +2851,5 @@
!LargeInteger class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Attic/LargeInt.st,v 1.79 1999-05-08 17:13:19 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Attic/LargeInt.st,v 1.80 1999-05-08 22:55:44 cg Exp $'
! !
--- a/LargeInteger.st Sat May 08 20:14:17 1999 +0200
+++ b/LargeInteger.st Sun May 09 00:55:44 1999 +0200
@@ -234,9 +234,9 @@
"create and return a new LargeInteger with value taken from
the argument, aSmallInteger.
Notice:
- this should be only used internally, since such small
- largeIntegers do not normally occur in the system.
- (They are used by myself)
+ this should be only used internally, since such small
+ largeIntegers do not normally occur in the system.
+ (They are used by myself)
May change/be removed without notice."
^ self basicNew value:aSmallInteger
@@ -421,33 +421,33 @@
Use a special method for this case ...
"
(cls == SmallInteger) ifTrue:[
- abs := aNumber.
- abs := abs abs.
- (abs between:1 and:16r00ffffff) ifTrue:[
- divMod := self absFastDivMod:abs.
- ] ifFalse:[
- n := abs asLargeInteger.
- ].
+ abs := aNumber.
+ abs := abs abs.
+ (abs between:1 and:16r00ffffff) ifTrue:[
+ divMod := self absFastDivMod:abs.
+ ] ifFalse:[
+ n := abs asLargeInteger.
+ ].
] ifFalse:[
- "
- if the argument is not a largeInteger, coerce
- "
- (cls == self class) ifFalse:[
- ^ self retry:#// coercing:aNumber
- ].
- n := aNumber
+ "
+ if the argument is not a largeInteger, coerce
+ "
+ (cls == self class) ifFalse:[
+ ^ self retry:#// coercing:aNumber
+ ].
+ n := aNumber
].
divMod isNil ifTrue:[
- divMod := self absDivMod:n.
+ divMod := self absDivMod:n.
].
quo := divMod at:1.
(sign == aNumber sign) ifFalse:[
- "/ adjust for truncation if negative and there is a remainder ...
- quo := quo sign:-1.
- (divMod at:2) == 0 ifFalse:[
- ^ quo - 1
- ].
+ "/ adjust for truncation if negative and there is a remainder ...
+ quo := quo sign:-1.
+ (divMod at:2) == 0 ifFalse:[
+ ^ quo - 1
+ ].
].
^ quo
@@ -485,11 +485,11 @@
|abs rem negativeDivisor|
aNumber negative ifTrue:[
- negativeDivisor := true.
- abs := aNumber negated.
+ negativeDivisor := true.
+ abs := aNumber negated.
] ifFalse:[
- negativeDivisor := false.
- abs := aNumber.
+ negativeDivisor := false.
+ abs := aNumber.
].
"
@@ -497,33 +497,33 @@
Use a special method for this case ...
"
(aNumber class == SmallInteger) ifTrue:[
- (abs between:1 and:16r00ffffff) ifTrue:[
- rem := (self absFastDivMod:abs) at:2.
- ] ifFalse:[
- rem := self absMod:abs asLargeInteger
- ].
+ (abs between:1 and:16r00ffffff) ifTrue:[
+ rem := (self absFastDivMod:abs) at:2.
+ ] ifFalse:[
+ rem := self absMod:abs asLargeInteger
+ ].
] ifFalse:[
- "
- if the argument is not a largeInteger, coerce
- "
- (aNumber class == self class) ifFalse:[
- ^ self retry:#\\ coercing:aNumber
- ].
-
- rem := self absMod:abs.
+ "
+ if the argument is not a largeInteger, coerce
+ "
+ (aNumber class == self class) ifFalse:[
+ ^ self retry:#\\ coercing:aNumber
+ ].
+
+ rem := self absMod:abs.
].
rem = 0 ifFalse:[
- negativeDivisor ifTrue:[
- rem := rem sign:-1
- ].
- (self negative ~~ negativeDivisor) ifTrue:[
- "different sign, so remainder would have been negative.
- rem has been rounded toward zero, this code will simulate
- rounding to negative infinity."
-
- rem := aNumber - rem.
- ].
+ negativeDivisor ifTrue:[
+ rem := rem sign:-1
+ ].
+ (self negative ~~ negativeDivisor) ifTrue:[
+ "different sign, so remainder would have been negative.
+ rem has been rounded toward zero, this code will simulate
+ rounding to negative infinity."
+
+ rem := aNumber - rem.
+ ].
].
^ rem
@@ -567,19 +567,19 @@
cls := aNumber class.
(cls == SmallInteger) ifTrue:[
- "
- this is the common case, dividing by a SmallInteger.
- Use a special method for this case ...
- "
- (aNumber between:1 and:16r00ffffff) ifTrue:[
- ^ self absFastDivMod:aNumber abs.
- ].
- n := aNumber asLargeInteger.
+ "
+ this is the common case, dividing by a SmallInteger.
+ Use a special method for this case ...
+ "
+ (aNumber between:1 and:16r00ffffff) ifTrue:[
+ ^ self absFastDivMod:aNumber abs.
+ ].
+ n := aNumber asLargeInteger.
] ifFalse:[
- (cls == self class) ifFalse:[
- ^ super divMod:aNumber
- ].
- n := aNumber.
+ (cls == self class) ifFalse:[
+ ^ super divMod:aNumber
+ ].
+ n := aNumber.
].
^ self absDivMod:n abs
@@ -676,26 +676,26 @@
Use a special method for this case ...
"
(aNumber class == SmallInteger) ifTrue:[
- abs := aNumber.
- abs := abs abs.
- (abs between:1 and:16r00ffffff) ifTrue:[
- quo := (self absFastDivMod:abs) at:1.
- (sign == otherSign) ifTrue:[^ quo].
- ^ quo sign:-1
- ]
+ abs := aNumber.
+ abs := abs abs.
+ (abs between:1 and:16r00ffffff) ifTrue:[
+ quo := (self absFastDivMod:abs) at:1.
+ (sign == otherSign) ifTrue:[^ quo].
+ ^ quo sign:-1
+ ]
].
"
if the argument is not a largeInteger, coerce
"
(aNumber class == self class) ifFalse:[
- ^ self retry:#quo: coercing:aNumber
+ ^ self retry:#quo: coercing:aNumber
].
sign < 0 ifTrue:[
- (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber negated) at:1].
+ (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber negated) at:1].
] ifFalse:[
- (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber) at:1].
+ (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber) at:1].
].
^ ((self absDivMod:aNumber) at:1) sign:-1
@@ -736,26 +736,26 @@
Use special code for this case ...
"
(aNumber class == SmallInteger) ifTrue:[
- abs := aNumber.
- abs := abs abs.
- (abs between:1 and:16r00ffffff) ifTrue:[
- rem := (self absFastDivMod:abs) at:2.
- ] ifFalse:[
- rem := self absMod:abs asLargeInteger
- ].
+ abs := aNumber.
+ abs := abs abs.
+ (abs between:1 and:16r00ffffff) ifTrue:[
+ rem := (self absFastDivMod:abs) at:2.
+ ] ifFalse:[
+ rem := self absMod:abs asLargeInteger
+ ].
] ifFalse:[
- "
- if the argument is not a largeInteger, coerce
- "
- (aNumber class == self class) ifFalse:[
- ^ self retry:#rem coercing:aNumber
- ].
-
- rem := self absMod:aNumber
+ "
+ if the argument is not a largeInteger, coerce
+ "
+ (aNumber class == self class) ifFalse:[
+ ^ self retry:#rem coercing:aNumber
+ ].
+
+ rem := self absMod:aNumber
].
sign < 0 ifTrue:[
- ^ rem sign:-1
+ ^ rem sign:-1
].
^ rem
@@ -847,10 +847,10 @@
|t digits|
sign < 0 ifFalse:[
- index > digitByteArray size ifTrue:[
- ^ 0
- ].
- ^ digitByteArray at:index.
+ index > digitByteArray size ifTrue:[
+ ^ 0
+ ].
+ ^ digitByteArray at:index.
].
"/ negative int - do 2's complement here
@@ -858,7 +858,7 @@
t sign:1.
digits := t digits.
index > digits size ifTrue:[
- ^ 16rFF
+ ^ 16rFF
].
^ digits at:index.
@@ -1271,7 +1271,7 @@
"/ speed up compare to 0
(aNumber == 0 and:[sign == 0]) ifTrue:[
- ^ true
+ ^ true
].
(aNumber class == self class) ifFalse:[
@@ -1668,22 +1668,22 @@
shift "{ Class: SmallInteger }" |
anInteger == 0 ifTrue:[
- ^ DivisionByZeroSignal raise
+ ^ DivisionByZeroSignal raise
].
self = anInteger ifTrue:[
- ^ Array with:1 with:0
+ ^ Array with:1 with:0
].
shift := self highBit - anInteger highBit.
dividend := self simpleDeepCopy sign:1.
shift < 0 ifTrue:[
- ^ Array with:0 with:dividend.
+ ^ Array with:0 with:dividend.
].
shift == 0 ifTrue:[
- divisor := anInteger simpleDeepCopy.
+ divisor := anInteger simpleDeepCopy.
] ifFalse:[
- divisor := anInteger bitShift:shift.
+ divisor := anInteger bitShift:shift.
].
quo := self class basicNew numberOfDigits:((shift // 8) + 1).
@@ -1691,14 +1691,14 @@
shift := shift + 1.
[shift > 0] whileTrue:[
- (dividend absLess:divisor) ifFalse:[
- digits bitSetAt:shift.
- (dividend absSubtract: divisor) ifFalse:[ "result == 0"
- ^ Array with:quo compressed with:dividend compressed
- ].
- ].
- shift := shift - 1.
- divisor div2.
+ (dividend absLess:divisor) ifFalse:[
+ digits bitSetAt:shift.
+ (dividend absSubtract: divisor) ifFalse:[ "result == 0"
+ ^ Array with:quo compressed with:dividend compressed
+ ].
+ ].
+ shift := shift - 1.
+ divisor div2.
].
^ Array with:quo compressed with:dividend compressed
@@ -1733,17 +1733,17 @@
"/ numbers to be compared ...
[(digitByteArray basicAt:len1) == 0] whileTrue:[
- len1 := len1 - 1
+ len1 := len1 - 1
].
[(otherDigitByteArray basicAt:len2) == 0] whileTrue:[
- len2 := len2 - 1
+ len2 := len2 - 1
].
(len1 ~~ len2) ifTrue:[^ false].
[len1 > 0] whileTrue:[
- d1 := digitByteArray basicAt:len1.
- d2 := otherDigitByteArray basicAt:len1.
- (d1 ~~ d2) ifTrue:[^ false].
- len1 := len1 - 1
+ d1 := digitByteArray basicAt:len1.
+ d2 := otherDigitByteArray basicAt:len1.
+ (d1 ~~ d2) ifTrue:[^ false].
+ len1 := len1 - 1
].
^ true
@@ -1761,12 +1761,12 @@
ok|
aPositiveSmallInteger == 0 ifTrue:[
- ^ DivisionByZeroSignal raise
+ ^ DivisionByZeroSignal raise
].
"This cannot happen (if always normalized)
self < aPositiveSmallInteger ifTrue:[
- ^ Array with:0 with:self
+ ^ Array with:0 with:self
].
"
count := digitByteArray size.
@@ -1781,67 +1781,67 @@
if (__isByteArray(__digits)
&& __isByteArray(newDigitByteArray)
&& __bothSmallInteger(count, aPositiveSmallInteger)) {
- unsigned INT rest = 0;
- int index = __intVal(count);
- int index0;
- unsigned INT divisor = __intVal(aPositiveSmallInteger);
- unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element;
- unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element;
-
- index0 = index - 1;
+ unsigned INT rest = 0;
+ int index = __intVal(count);
+ int index0;
+ unsigned INT divisor = __intVal(aPositiveSmallInteger);
+ unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element;
+ unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element;
+
+ index0 = index - 1;
#ifdef i386
- if (divisor <= 0xFFFF) {
- if ((index & 1) == 0) { /* even number of bytes */
- while (index > 1) {
- unsigned INT t;
- unsigned INT div;
+ if (divisor <= 0xFFFF) {
+ if ((index & 1) == 0) { /* even number of bytes */
+ while (index > 1) {
+ unsigned INT t;
+ unsigned INT div;
# ifdef i386 /* LSB_FIRST */
- index -= 2;
- t = *((unsigned short *)(&digitBytes[index]));
+ index -= 2;
+ t = *((unsigned short *)(&digitBytes[index]));
# else
- index--;
- t = digitBytes[index];
- index--;
- t = (t << 8) | digitBytes[index];
+ index--;
+ t = digitBytes[index];
+ index--;
+ t = (t << 8) | digitBytes[index];
# endif
- t = t | (rest << 16);
- div = t / divisor;
- rest = t % divisor;
+ t = t | (rest << 16);
+ div = t / divisor;
+ rest = t % divisor;
# ifdef i386 /* LSB_FIRST */
- *((unsigned short *)(&resultBytes[index])) = (div & 0xFFFF);
+ *((unsigned short *)(&resultBytes[index])) = (div & 0xFFFF);
# else
- resultBytes[index+1] = (div >> 8);
- resultBytes[index] = (div & 0xFF);
+ resultBytes[index+1] = (div >> 8);
+ resultBytes[index] = (div & 0xFF);
# endif
- }
- }
- }
+ }
+ }
+ }
#endif
- while (index > 0) {
- unsigned INT t;
-
- index--;
- t = digitBytes[index];
- t = t | (rest << 8);
- resultBytes[index] = t / divisor;
- rest = t % divisor;
- }
- prevRest = __MKSMALLINT(rest);
- ok = true;
-
- /*
- * no need to normalize ?
- */
- while ((index0 > sizeof(INT)) && (resultBytes[index0]==0)) {
- index0--;
- }
-
- if ((index0 > sizeof(INT))
- && (resultBytes[index0-1])) {
- RETURN ( __ARRAY_WITH2(result, prevRest));
- }
+ while (index > 0) {
+ unsigned INT t;
+
+ index--;
+ t = digitBytes[index];
+ t = t | (rest << 8);
+ resultBytes[index] = t / divisor;
+ rest = t % divisor;
+ }
+ prevRest = __MKSMALLINT(rest);
+ ok = true;
+
+ /*
+ * no need to normalize ?
+ */
+ while ((index0 > sizeof(INT)) && (resultBytes[index0]==0)) {
+ index0--;
+ }
+
+ if ((index0 > sizeof(INT))
+ && (resultBytes[index0-1])) {
+ RETURN ( __ARRAY_WITH2(result, prevRest));
+ }
}
%}.
"
@@ -1849,7 +1849,7 @@
(could also do a primitiveFailure here)
"
ok ifFalse:[
- self primitiveFailed
+ self primitiveFailed
].
^ Array with:(result compressed) with:prevRest
@@ -1943,7 +1943,7 @@
((aSmallInteger < (SmallInteger minVal + 255))
or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
- ^ self absPlus:(LargeInteger value:aSmallInteger).
+ ^ self absPlus:(LargeInteger value:aSmallInteger).
].
len := digitByteArray size.
@@ -1956,63 +1956,63 @@
if (__isByteArray(__INST(digitByteArray))
&& __isByteArray(resultDigitByteArray)
&& __isSmallInteger(aSmallInteger)) {
- 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 __lastDigit = 0;
-
- if (__carry < 0) {
- __carry = -__carry;
- }
-
- while (__carry) {
- if (__index <= __len) {
- __carry += __src[__index-1];
- }
- __dst[__index-1] = __lastDigit = __carry & 0xFF;
- __carry >>= 8;
- __index++;
- }
- if (__index <= __intVal(rsltLen)) {
- while (__index <= __len) {
- __dst[__index-1] = __src[__index-1];
- __index++;
- }
- __lastDigit = 0;
- }
- if (lastDigit) {
- RETURN (result);
- }
- ok = true;
+ 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 __lastDigit = 0;
+
+ if (__carry < 0) {
+ __carry = -__carry;
+ }
+
+ while (__carry) {
+ if (__index <= __len) {
+ __carry += __src[__index-1];
+ }
+ __dst[__index-1] = __lastDigit = __carry & 0xFF;
+ __carry >>= 8;
+ __index++;
+ }
+ if (__index <= __intVal(rsltLen)) {
+ while (__index <= __len) {
+ __dst[__index-1] = __src[__index-1];
+ __index++;
+ }
+ __lastDigit = 0;
+ }
+ if (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
@@ -2040,22 +2040,22 @@
"/ numbers to be compared ...
[myLen > 0 and:[(digitByteArray basicAt:myLen) == 0]] whileTrue:[
- myLen := myLen - 1
+ myLen := myLen - 1
].
[otherLen > 0 and:[(otherDigitByteArray basicAt:otherLen) == 0]] whileTrue:[
- otherLen := otherLen - 1
+ otherLen := otherLen - 1
].
(myLen < otherLen) ifTrue:[^ true].
(myLen > otherLen) ifTrue:[^ false].
[myLen > 0] whileTrue:[
- d1 := digitByteArray basicAt:myLen.
- d2 := otherDigitByteArray basicAt:myLen.
- d1 == d2 ifFalse:[
- (d1 < d2) ifTrue:[^ true].
- ^ false
- ].
- myLen := myLen - 1
+ d1 := digitByteArray basicAt:myLen.
+ d2 := otherDigitByteArray basicAt:myLen.
+ d1 == d2 ifFalse:[
+ (d1 < d2) ifTrue:[^ true].
+ ^ false
+ ].
+ myLen := myLen - 1
].
^ false
@@ -2083,22 +2083,22 @@
"/ numbers to be compared ...
[(digitByteArray basicAt:myLen) == 0] whileTrue:[
- myLen := myLen - 1
+ myLen := myLen - 1
].
[(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[
- otherLen := otherLen - 1
+ otherLen := otherLen - 1
].
(myLen < otherLen) ifTrue:[^ true].
(myLen > otherLen) ifTrue:[^ false].
[myLen > 0] whileTrue:[
- d1 := digitByteArray basicAt:myLen.
- d2 := otherDigitByteArray basicAt:myLen.
- d1 == d2 ifFalse:[
- (d1 < d2) ifTrue:[^ true].
- ^ false.
- ].
- myLen := myLen - 1
+ d1 := digitByteArray basicAt:myLen.
+ d2 := otherDigitByteArray basicAt:myLen.
+ d1 == d2 ifFalse:[
+ (d1 < d2) ifTrue:[^ true].
+ ^ false.
+ ].
+ myLen := myLen - 1
].
^ true
@@ -2209,34 +2209,34 @@
shift "{ Class: SmallInteger }" |
anInteger == 0 ifTrue:[
- ^ DivisionByZeroSignal raise
+ ^ DivisionByZeroSignal raise
].
self = anInteger ifTrue:[
- ^ 0
+ ^ 0
].
shift := self highBit - anInteger highBit.
dividend := self simpleDeepCopy sign:1.
shift < 0 ifTrue:[
- ^ dividend.
+ ^ dividend.
].
shift == 0 ifTrue:[
- divisor := anInteger simpleDeepCopy.
+ divisor := anInteger simpleDeepCopy.
] ifFalse:[
- divisor := anInteger bitShift:shift.
+ divisor := anInteger bitShift:shift.
].
shift := shift + 1.
[shift > 0] whileTrue:[
- (dividend absLess:divisor) ifFalse:[
- (dividend absSubtract: divisor) ifFalse:[ "result == 0"
- ^ dividend compressed
- ].
- ].
- shift := shift - 1.
- divisor div2.
+ (dividend absLess:divisor) ifFalse:[
+ (dividend absSubtract: divisor) ifFalse:[ "result == 0"
+ ^ dividend compressed
+ ].
+ ].
+ shift := shift - 1.
+ divisor div2.
].
^ dividend compressed
@@ -2277,56 +2277,63 @@
&& __isByteArray(otherDigitByteArray)
&& __isByteArray(resultDigitByteArray)
&& __bothSmallInteger(len1, len2)) {
- unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
- unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
- unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
- unsigned char *_p1, *_p2, *_pResult, *_pResult1;
- unsigned INT _v;
- int _len1 = __intVal(len1);
- int _len2 = __intVal(len2);
-
- /*
- * the code below is a q&d hack - it certainly needs some more thought,
- * if large numbers are multiplied often ...
- */
- for (_p1 = myBytes; _p1 < myBytes + _len1; _p1++) {
- _pResult = resultBytes + (_p1 - myBytes);
- for (_p2 = otherBytes; _p2 < otherBytes + _len2; _p2++) {
- _v = ((*_p1) * (*_p2)) + *_pResult;
- *_pResult = _v & 0xFF;
- _v >>= 8; /* now _v contains the carry*/
- _pResult++;
- if (_v) {
- for (_pResult1 = _pResult; _v; _pResult1++) {
- _v += *_pResult1;
- *_pResult1 = _v & 0xFF;
- _v >>= 8;
- }
- }
- }
- }
- ok = true;
+ unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
+ unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+ unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+ unsigned char *_p1, *_p2, *_pResult, *_pResult0, *_pResult1, *_p1Last, *_p2Last;
+ unsigned INT _v;
+ int _len1 = __intVal(len1);
+ int _len2 = __intVal(len2);
+
+ /*
+ * the code below is a q&d hack - it certainly needs some more thought,
+ * if large numbers are multiplied often ...
+ */
+ _p1Last = myBytes + _len1 - 1; /* the last byte */
+ _p2Last = otherBytes + _len2 - 1; /* the last byte */
+ _pResult0 = resultBytes;
+ for (_p1 = myBytes; _p1 <= _p1Last; _p1++, _pResult0++) {
+ unsigned int byte1 = *_p1;
+
+ _pResult = _pResult0;
+ _p2 = otherBytes;
+ while (_p2 <= _p2Last) {
+ _v = (byte1 * _p2[0]) + _pResult[0];
+ _pResult[0] = _v & 0xFF;
+ _v >>= 8; /* now _v contains the carry*/
+ _pResult++;
+ if (_v) {
+ for (_pResult1 = _pResult; _v; _pResult1++) {
+ _v += _pResult1[0];
+ _pResult1[0] = _v & 0xFF;
+ _v >>= 8;
+ }
+ }
+ _p2 ++;
+ }
+ }
+ ok = true;
}
%}.
ok ifFalse:[
- 1 to:len1 do:[:index1 |
- 1 to:len2 do:[:index2 |
- dstIndex := index1 + index2 - 1.
- prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
- prod := prod + (resultDigitByteArray basicAt:dstIndex).
- resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
- carry := prod bitShift:-8.
- carry ~~ 0 ifTrue:[
- idx := dstIndex + 1.
- [carry ~~ 0] whileTrue:[
- v := (resultDigitByteArray basicAt:idx) + carry.
- resultDigitByteArray basicAt:idx put:(v bitAnd:255).
- carry := v bitShift:-8.
- idx := idx + 1
- ]
- ]
- ]
- ].
+ 1 to:len1 do:[:index1 |
+ 1 to:len2 do:[:index2 |
+ dstIndex := index1 + index2 - 1.
+ prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
+ prod := prod + (resultDigitByteArray basicAt:dstIndex).
+ resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
+ carry := prod bitShift:-8.
+ carry ~~ 0 ifTrue:[
+ idx := dstIndex + 1.
+ [carry ~~ 0] whileTrue:[
+ v := (resultDigitByteArray basicAt:idx) + carry.
+ resultDigitByteArray basicAt:idx put:(v bitAnd:255).
+ carry := v bitShift:-8.
+ idx := idx + 1
+ ]
+ ]
+ ]
+ ].
].
^ result compressed
!
@@ -2349,200 +2356,200 @@
if (__isByteArray(_digitByteArray)
&& __isByteArray(otherDigitByteArray)) {
- int _len1, _len2, _newLen;
- unsigned char *_myDigits, *_otherDigits, *_newDigits;
- int _index, _carry;
- int _comLen;
-
- _len1 = __byteArraySize(_digitByteArray);
- _len2 = __byteArraySize(otherDigitByteArray);
-
- _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
- _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
-
- if (_len1 < _len2) {
- _comLen = _len1;
- _newLen = _len2;
- if (_otherDigits[_len2 - 1] == 0xFF) _newLen++;
- } else if (_len2 < _len1) {
- _comLen = _len2;
- _newLen = _len1;
- if (_myDigits[_len1 - 1] == 0xFF) _newLen++;
- } else {
- /*
- * there can only be an overflow from the high bytes,
- * if their sum is >= 255
- */
- _newLen = _len1;
- if ((_otherDigits[_len2 - 1] + _myDigits[_len1 - 1]) >= 0xFF) {
- _newLen++;
- } else {
+ int _len1, _len2, _newLen;
+ unsigned char *_myDigits, *_otherDigits, *_newDigits;
+ int _index, _carry;
+ int _comLen;
+
+ _len1 = __byteArraySize(_digitByteArray);
+ _len2 = __byteArraySize(otherDigitByteArray);
+
+ _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+ _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+
+ if (_len1 < _len2) {
+ _comLen = _len1;
+ _newLen = _len2;
+ if (_otherDigits[_len2 - 1] == 0xFF) _newLen++;
+ } else if (_len2 < _len1) {
+ _comLen = _len2;
+ _newLen = _len1;
+ if (_myDigits[_len1 - 1] == 0xFF) _newLen++;
+ } else {
+ /*
+ * there can only be an overflow from the high bytes,
+ * if their sum is >= 255
+ */
+ _newLen = _len1;
+ if ((_otherDigits[_len2 - 1] + _myDigits[_len1 - 1]) >= 0xFF) {
+ _newLen++;
+ } else {
#if defined(i386) || defined(alpha) /* actually: LSB_FIRST */
- if (_newLen == sizeof(INT)) {
- /*
- * two 32bit numbers, no carry - a very common case ...
- */
- unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits;
- RETURN (__MKULARGEINT(_sum));
- }
+ if (_newLen == sizeof(INT)) {
+ /*
+ * two 32bit numbers, no carry - a very common case ...
+ */
+ unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits;
+ RETURN (__MKULARGEINT(_sum));
+ }
#endif /* not LSB_FIRST */
- }
- _comLen = _len1;
- }
- resultDigitByteArray = __BYTEARRAY_UNINITIALIZED_NEW_INT(_newLen);
-
- /*
- * must refetch - GC could have been invoked
- */
- _digitByteArray = __INST(digitByteArray);
-
- _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
- _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
- _newDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
-
- /*
- * add them ...
- */
- _index = 1;
- _carry = 0;
+ }
+ _comLen = _len1;
+ }
+ resultDigitByteArray = __BYTEARRAY_UNINITIALIZED_NEW_INT(_newLen);
+
+ /*
+ * must refetch - GC could have been invoked
+ */
+ _digitByteArray = __INST(digitByteArray);
+
+ _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+ _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+ _newDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+
+ /*
+ * add them ...
+ */
+ _index = 1;
+ _carry = 0;
#if defined(i386) || defined(alpha) /* actually: LSB first */
# ifdef INT64
- /*
- * have a 64bit integer type;
- * add long-wise
- */
- while (_index < _comLen) {
- UINT64 _sum;
-
- _sum = _carry;
- _sum += *(unsigned *)(&(_myDigits[_index - 1]));
- _sum += *(unsigned *)(&(_otherDigits[_index - 1]));
- _carry = _sum >> 32;
- _sum = _sum & 0xFFFFFFFF;
- *(unsigned *)(&(_newDigits[_index - 1])) = _sum;
- _index += 4;
- }
+ /*
+ * have a 64bit integer type;
+ * add long-wise
+ */
+ while (_index < _comLen) {
+ UINT64 _sum;
+
+ _sum = _carry;
+ _sum += *(unsigned *)(&(_myDigits[_index - 1]));
+ _sum += *(unsigned *)(&(_otherDigits[_index - 1]));
+ _carry = _sum >> 32;
+ _sum = _sum & 0xFFFFFFFF;
+ *(unsigned *)(&(_newDigits[_index - 1])) = _sum;
+ _index += 4;
+ }
# endif
- /*
- * add short-wise
- */
- while (_index < _comLen) {
- unsigned int _sum;
-
- _sum = _carry;
- _sum += *(unsigned short *)(&(_myDigits[_index - 1]));
- _sum += *(unsigned short *)(&(_otherDigits[_index - 1]));
- _carry = _sum >> 16;
- _sum = _sum & 0xFFFF;
- *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
- _index += 2;
- }
+ /*
+ * add short-wise
+ */
+ while (_index < _comLen) {
+ unsigned int _sum;
+
+ _sum = _carry;
+ _sum += *(unsigned short *)(&(_myDigits[_index - 1]));
+ _sum += *(unsigned short *)(&(_otherDigits[_index - 1]));
+ _carry = _sum >> 16;
+ _sum = _sum & 0xFFFF;
+ *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
+ _index += 2;
+ }
#endif
- /*
- * add byte
- */
- while (_index <= _comLen) {
- unsigned int _sum;
-
- _sum = _carry;
- _sum += _myDigits[_index - 1];
- _sum += _otherDigits[_index - 1];
- _carry = _sum >> 8;
- _sum = _sum & 0xFF;
- _newDigits[_index - 1] = _sum;
- _index++;
- }
-
- /*
- * rest
- */
- while (_index <= _newLen) {
- unsigned int _sum;
-
- _sum = _carry;
- if (_index <= _len1) {
- _sum += _myDigits[_index - 1];
- if (_index <= _len2) {
- _sum += _otherDigits[_index - 1];
- }
- } else {
- if (_index <= _len2) {
- _sum += _otherDigits[_index - 1];
- }
- }
- _carry = _sum >> 8;
- _sum = _sum & 0xFF;
- _newDigits[_index - 1] = _sum;
- _index++;
- }
+ /*
+ * add byte
+ */
+ while (_index <= _comLen) {
+ unsigned int _sum;
+
+ _sum = _carry;
+ _sum += _myDigits[_index - 1];
+ _sum += _otherDigits[_index - 1];
+ _carry = _sum >> 8;
+ _sum = _sum & 0xFF;
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
+
+ /*
+ * rest
+ */
+ while (_index <= _newLen) {
+ unsigned int _sum;
+
+ _sum = _carry;
+ if (_index <= _len1) {
+ _sum += _myDigits[_index - 1];
+ if (_index <= _len2) {
+ _sum += _otherDigits[_index - 1];
+ }
+ } else {
+ if (_index <= _len2) {
+ _sum += _otherDigits[_index - 1];
+ }
+ }
+ _carry = _sum >> 8;
+ _sum = _sum & 0xFF;
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
}
%}.
resultDigitByteArray notNil ifTrue:[
- result := self class basicNew.
- result setDigits:resultDigitByteArray.
+ result := self class basicNew.
+ result setDigits:resultDigitByteArray.
] ifFalse:[
- len1 := digitByteArray size.
- len2 := otherDigitByteArray size.
-
- "/ earlier versions estimated the newLength as:
- "/ (len1 max:len2) + 1
- "/ and reduced the result.
- "/ however, if one of the addends is smaller,
- "/ the result will never require another digit,
- "/ if the highest digit of the larger addent is
- "/ not equal to 255. Therefore, in most cases,
- "/ we can avoid the computation and resizing
- "/ in #reduced.
-
- len1 < len2 ifTrue:[
- newLen := len2.
- (otherDigitByteArray at:len2) == 16rFF ifTrue:[
- newLen := newLen + 1
- ]
- ] ifFalse:[
- len2 < len1 ifTrue:[
- newLen := len1.
- (digitByteArray at:len1) == 16rFF ifTrue:[
- newLen := newLen + 1
- ]
- ] ifFalse:[
- newLen := len1 + 1.
- ]
- ].
-
- result := self class basicNew numberOfDigits:newLen.
- resultDigitByteArray := result digits.
-
- index := 1.
- carry := 0.
-
- done := false.
- [done] whileFalse:[
- sum := carry.
- (index <= len1) ifTrue:[
- sum := sum + (digitByteArray basicAt:index).
- (index <= len2) ifTrue:[
- sum := sum + (otherDigitByteArray basicAt:index)
- ]
- ] ifFalse:[
- (index <= len2) ifTrue:[
- sum := sum + (otherDigitByteArray basicAt:index)
- ] ifFalse:[
- "end reached"
- done := true
- ]
- ].
- (sum >= 16r100) ifTrue:[
- carry := 1.
- sum := sum - 16r100
- ] ifFalse:[
- carry := 0
- ].
- resultDigitByteArray basicAt:index put:sum.
- index := index + 1
- ].
+ len1 := digitByteArray size.
+ len2 := otherDigitByteArray size.
+
+ "/ earlier versions estimated the newLength as:
+ "/ (len1 max:len2) + 1
+ "/ and reduced the result.
+ "/ however, if one of the addends is smaller,
+ "/ the result will never require another digit,
+ "/ if the highest digit of the larger addent is
+ "/ not equal to 255. Therefore, in most cases,
+ "/ we can avoid the computation and resizing
+ "/ in #reduced.
+
+ len1 < len2 ifTrue:[
+ newLen := len2.
+ (otherDigitByteArray at:len2) == 16rFF ifTrue:[
+ newLen := newLen + 1
+ ]
+ ] ifFalse:[
+ len2 < len1 ifTrue:[
+ newLen := len1.
+ (digitByteArray at:len1) == 16rFF ifTrue:[
+ newLen := newLen + 1
+ ]
+ ] ifFalse:[
+ newLen := len1 + 1.
+ ]
+ ].
+
+ result := self class basicNew numberOfDigits:newLen.
+ resultDigitByteArray := result digits.
+
+ index := 1.
+ carry := 0.
+
+ done := false.
+ [done] whileFalse:[
+ sum := carry.
+ (index <= len1) ifTrue:[
+ sum := sum + (digitByteArray basicAt:index).
+ (index <= len2) ifTrue:[
+ sum := sum + (otherDigitByteArray basicAt:index)
+ ]
+ ] ifFalse:[
+ (index <= len2) ifTrue:[
+ sum := sum + (otherDigitByteArray basicAt:index)
+ ] ifFalse:[
+ "end reached"
+ done := true
+ ]
+ ].
+ (sum >= 16r100) ifTrue:[
+ carry := 1.
+ sum := sum - 16r100
+ ] ifFalse:[
+ carry := 0
+ ].
+ resultDigitByteArray basicAt:index put:sum.
+ index := index + 1
+ ].
].
^ result compressed
@@ -2571,12 +2578,12 @@
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.
@@ -2584,26 +2591,26 @@
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
+ 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
@@ -2622,66 +2629,66 @@
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(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
@@ -2707,57 +2714,57 @@
b := digitByteArray at:nBytes.
(b bitAnd:16r80) ~~ 0 ifTrue:[
- "/ need another byte
- nBytes := nBytes + 1.
- t := ByteArray uninitializedNew:nBytes.
- t replaceFrom:1 to:nBytes-1 with:digitByteArray startingAt:1.
- t at:nBytes put:0.
- digitByteArray := t.
+ "/ need another byte
+ nBytes := nBytes + 1.
+ t := ByteArray uninitializedNew:nBytes.
+ t replaceFrom:1 to:nBytes-1 with:digitByteArray startingAt:1.
+ t at:nBytes put:0.
+ digitByteArray := t.
].
%{
OBJ __digits = __INST(digitByteArray);
if (__isByteArray(__digits)) {
- int __nBytes = __intVal(nBytes);
- unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
- unsigned INT __carry = 0, __newCarry, __this;
- int __idx;
+ int __nBytes = __intVal(nBytes);
+ unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
+ unsigned INT __carry = 0, __newCarry, __this;
+ int __idx;
#if defined(alpha64)
- if (sizeof(unsigned INT) == 8) {
- while (__nBytes >= 8) {
- __this = ((unsigned INT *)__bp)[0];
- __newCarry = (__this >> 63) /* & 1 */;
- ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
- __carry = __newCarry;
- __bp += 8;
- __nBytes -= 8;
- }
- }
+ if (sizeof(unsigned INT) == 8) {
+ while (__nBytes >= 8) {
+ __this = ((unsigned INT *)__bp)[0];
+ __newCarry = (__this >> 63) /* & 1 */;
+ ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp += 8;
+ __nBytes -= 8;
+ }
+ }
#else
# if defined(i386) /* XXX actually: LSB_FIRST */
- if (sizeof(unsigned INT) == 4) {
- while (__nBytes >= 4) {
- __this = ((unsigned INT *)__bp)[0];
- __newCarry = (__this >> 31) /* & 1 */;
- ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
- __carry = __newCarry;
- __bp += 4;
- __nBytes -= 4;
- }
- }
+ if (sizeof(unsigned INT) == 4) {
+ while (__nBytes >= 4) {
+ __this = ((unsigned INT *)__bp)[0];
+ __newCarry = (__this >> 31) /* & 1 */;
+ ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp += 4;
+ __nBytes -= 4;
+ }
+ }
# endif
#endif
- while (__nBytes) {
- __this = __bp[0];
- __newCarry = (__this >> 7) /* & 1 */;
- __bp[0] = (__this << 1) | __carry;
- __carry = __newCarry;
- __bp++;
- __nBytes--;
- }
- RETURN (self);
+ while (__nBytes) {
+ __this = __bp[0];
+ __newCarry = (__this >> 7) /* & 1 */;
+ __bp[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp++;
+ __nBytes--;
+ }
+ RETURN (self);
}
%}.
self primitiveFailed
@@ -2844,5 +2851,5 @@
!LargeInteger class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.79 1999-05-08 17:13:19 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.80 1999-05-08 22:55:44 cg Exp $'
! !