--- a/LargeInteger.st Mon Jan 12 14:18:15 1998 +0100
+++ b/LargeInteger.st Mon Jan 12 14:18:47 1998 +0100
@@ -81,7 +81,7 @@
i printCR.
v := v * i.
(v / i) ~= last ifTrue:[
- self halt
+ self halt
].
last := v.
]
@@ -130,7 +130,7 @@
* aNumber
"return the product of the receiver and the argument, aNumber"
- |otherSign|
+ |otherSign numberClass|
(sign == 0) ifTrue:[^ 0]. "cannot happen if correctly normalized"
@@ -138,14 +138,14 @@
this is the common case, multiplying with SmallInteger.
Use a special method for this case ...
"
- (aNumber class == SmallInteger) ifTrue:[
+ ((numberClass := aNumber class) == SmallInteger) ifTrue:[
^ self productFromInteger:aNumber
].
"
if the argument is not a largeInteger, coerce
"
- (aNumber class == self class) ifFalse:[
+ (numberClass == self class) ifFalse:[
^ self retry:#* coercing:aNumber
].
@@ -158,7 +158,7 @@
+ aNumber
"return the sum of the receiver and the argument, aNumber"
- |otherSign|
+ |otherSign numberClass|
(sign == 0) ifTrue:[^ aNumber]. "cannot happen if correctly normalized"
@@ -166,14 +166,14 @@
this is the common case, adding a SmallInteger.
Use a special method for this case ...
"
- (aNumber class == SmallInteger) ifTrue:[
+ ((numberClass := aNumber class) == SmallInteger) ifTrue:[
^ self sumFromInteger:aNumber
].
"
if the argument is not a largeInteger, coerce
"
- (aNumber class == self class) ifFalse:[
+ (numberClass == self class) ifFalse:[
^ self retry:#+ coercing:aNumber
].
@@ -196,12 +196,14 @@
SmallInteger minVal
SmallInteger minVal - 1
"
+
+ "Modified: / 9.1.1998 / 13:26:28 / cg"
!
- aNumber
"return the difference of the receiver and the argument, aNumber"
- |otherSign|
+ |otherSign numberClass|
(sign == 0) ifTrue:[^ aNumber negated]. "cannot happen if correctly normalized"
@@ -209,23 +211,23 @@
this is the common case, subtracting a SmallInteger.
Use a special method for this case ...
"
- (aNumber class == SmallInteger) ifTrue:[
- sign < 0 ifTrue:[
+ ((numberClass := aNumber class) == SmallInteger) ifTrue:[
+ sign > 0 ifTrue:[
aNumber > 0 ifTrue:[
- ^ (self absFastPlus:aNumber) sign:-1
+ ^ self absFastMinus:aNumber
].
- ^ (self absFastMinus:aNumber) sign:-1
+ ^ self absFastPlus:aNumber
].
aNumber > 0 ifTrue:[
- ^ self absFastMinus:aNumber
+ ^ (self absFastPlus:aNumber) sign:-1
].
- ^ self absFastPlus:aNumber
+ ^ (self absFastMinus:aNumber) sign:-1
].
"
if the argument is not a largeInteger, coerce
"
- (aNumber class == self class) ifFalse:[
+ (numberClass == self class) ifFalse:[
^ self retry:#- coercing:aNumber
].
@@ -263,8 +265,8 @@
"return the quotient of the receiver and the argument, aNumber"
aNumber isInteger ifTrue:[
- ^ Fraction numerator:self
- denominator:aNumber
+ ^ Fraction numerator:self
+ denominator:aNumber
].
"this is a q&d hack - we loose lots of precision here ..."
@@ -458,7 +460,7 @@
special case for SmallInteger minVal
"
sign == 1 ifTrue:[
- sz := digitByteArray size.
+ sz := digitByteArray size.
%{
if (__intVal(sz) == sizeof(INT)) {
unsigned char *bp;
@@ -478,16 +480,16 @@
}
}
%}.
-"/ sz == 4 ifTrue:[
-"/ (digitByteArray at:1) == 0 ifTrue:[
-"/ (digitByteArray at:2) == 0 ifTrue:[
-"/ (digitByteArray at:3) == 0 ifTrue:[
-"/ (digitByteArray at:4) == 16r40 ifTrue:[
-"/ ^ SmallInteger minVal
-"/ ].
-"/ ]
-"/ ]
-"/ ]
+"/ sz == 4 ifTrue:[
+"/ (digitByteArray at:1) == 0 ifTrue:[
+"/ (digitByteArray at:2) == 0 ifTrue:[
+"/ (digitByteArray at:3) == 0 ifTrue:[
+"/ (digitByteArray at:4) == 16r40 ifTrue:[
+"/ ^ SmallInteger minVal
+"/ ].
+"/ ]
+"/ ]
+"/ ]
"/ ]
].
newNumber := self shallowCopy.
@@ -632,9 +634,9 @@
sz := digitByteArray size.
1 to:sz do:[:digitIndex |
- (byte := digitByteArray at:digitIndex) ~~ 0 ifTrue:[
- ^ (digitIndex-1)*8 + byte lowBit
- ]
+ (byte := digitByteArray at:digitIndex) ~~ 0 ifTrue:[
+ ^ (digitIndex-1)*8 + byte lowBit
+ ]
].
^ -1
@@ -687,7 +689,7 @@
l := digitByteArray size.
[l ~~ 0 and:[(digitByteArray at:l) == 0]] whileTrue:[
- l := l - 1.
+ l := l - 1.
].
^ l
@@ -799,8 +801,8 @@
_val = (_val + _digitBytes[1]) << 8;
_val += _digitBytes[0];
if (__INST(sign) == __MKSMALLINT(-1))
- _val = -_val;
- RETURN (__MKSMALLINT(_val));
+ _val = -_val;
+ RETURN (__MKSMALLINT(_val));
case 6:
_val = (_digitBytes[5]<<8);
_val = (_val + _digitBytes[4]) << 8;
@@ -809,8 +811,8 @@
_val = (_val + _digitBytes[1]) << 8;
_val += _digitBytes[0];
if (__INST(sign) == __MKSMALLINT(-1))
- _val = -_val;
- RETURN (__MKSMALLINT(_val));
+ _val = -_val;
+ RETURN (__MKSMALLINT(_val));
case 5:
_val = (_digitBytes[4]<<8);
_val = (_val + _digitBytes[3]) << 8;
@@ -818,23 +820,23 @@
_val = (_val + _digitBytes[1]) << 8;
_val += _digitBytes[0];
if (__INST(sign) == __MKSMALLINT(-1))
- _val = -_val;
- RETURN (__MKSMALLINT(_val));
+ _val = -_val;
+ RETURN (__MKSMALLINT(_val));
case 4:
_val = (_digitBytes[3]<<8);
_val = (_val + _digitBytes[2]) << 8;
_val = (_val + _digitBytes[1]) << 8;
_val += _digitBytes[0];
if (__INST(sign) == __MKSMALLINT(-1))
- _val = -_val;
- RETURN (__MKSMALLINT(_val));
+ _val = -_val;
+ RETURN (__MKSMALLINT(_val));
case 3:
_val = (_digitBytes[2]<<8);
_val = (_val + _digitBytes[1]) << 8;
_val += _digitBytes[0];
if (__INST(sign) == __MKSMALLINT(-1))
- _val = -_val;
- RETURN (__MKSMALLINT(_val));
+ _val = -_val;
+ RETURN (__MKSMALLINT(_val));
case 2:
_val = (_digitBytes[1]<<8) + _digitBytes[0];
if (__INST(sign) == __MKSMALLINT(-1))
@@ -994,34 +996,34 @@
absValue := absValue bitShift:-8.
absValue == 0 ifTrue:[
digitByteArray := ByteArray new:6.
- digitByteArray at:1 put:b1.
- digitByteArray at:2 put:b2.
- digitByteArray at:3 put:b3.
- digitByteArray at:4 put:b4.
- digitByteArray at:5 put:b5.
- digitByteArray at:6 put:b6.
+ digitByteArray at:1 put:b1.
+ digitByteArray at:2 put:b2.
+ digitByteArray at:3 put:b3.
+ digitByteArray at:4 put:b4.
+ digitByteArray at:5 put:b5.
+ digitByteArray at:6 put:b6.
] ifFalse:[
b7 := absValue bitAnd:16rFF.
absValue := absValue bitShift:-8.
absValue == 0 ifTrue:[
digitByteArray := ByteArray new:7.
- digitByteArray at:1 put:b1.
- digitByteArray at:2 put:b2.
- digitByteArray at:3 put:b3.
- digitByteArray at:4 put:b4.
- digitByteArray at:5 put:b5.
- digitByteArray at:6 put:b6.
- digitByteArray at:7 put:b7.
+ digitByteArray at:1 put:b1.
+ digitByteArray at:2 put:b2.
+ digitByteArray at:3 put:b3.
+ digitByteArray at:4 put:b4.
+ digitByteArray at:5 put:b5.
+ digitByteArray at:6 put:b6.
+ digitByteArray at:7 put:b7.
] ifFalse:[
digitByteArray := ByteArray new:8.
digitByteArray at:1 put:b1.
- digitByteArray at:2 put:b2.
- digitByteArray at:3 put:b3.
- digitByteArray at:4 put:b4.
- digitByteArray at:5 put:b5.
- digitByteArray at:6 put:b6.
- digitByteArray at:7 put:b7.
- digitByteArray at:7 put:absValue.
+ digitByteArray at:2 put:b2.
+ digitByteArray at:3 put:b3.
+ digitByteArray at:4 put:b4.
+ digitByteArray at:5 put:b5.
+ digitByteArray at:6 put:b6.
+ digitByteArray at:7 put:b7.
+ digitByteArray at:7 put:absValue.
]
]
]
@@ -1151,38 +1153,38 @@
num := anInteger abs.
(num > 16r3FFFFF) ifTrue:[
- "if num is too big (so that multiplying by a byte could create a Large)"
+ "if num is too big (so that multiplying by a byte could create a Large)"
- ^ anInteger retry:#* coercing:self
+ ^ anInteger retry:#* coercing:self
].
len := digitByteArray size.
val := num.
val <= 16rFF ifTrue:[
- lResult := len + 1.
+ lResult := len + 1.
] ifFalse:[
- val <= 16rFFFF ifTrue:[
- lResult := len + 2
- ] ifFalse:[
- val <= 16rFFFFFF ifTrue:[
- lResult := len + 4.
- ] ifFalse:[
- lResult := len + 6.
- ]
- ]
+ val <= 16rFFFF ifTrue:[
+ lResult := len + 2
+ ] ifFalse:[
+ val <= 16rFFFFFF ifTrue:[
+ lResult := len + 4.
+ ] ifFalse:[
+ lResult := len + 6.
+ ]
+ ]
].
resultDigitByteArray := ByteArray uninitializedNew:lResult.
result := self class basicNew setDigits:resultDigitByteArray.
anInteger < 0 ifTrue:[
- sign > 0 ifTrue:[
- result sign:-1
- ].
+ sign > 0 ifTrue:[
+ result sign:-1
+ ].
] ifFalse:[
- sign < 0 ifTrue:[
- result sign:sign
- ]
+ sign < 0 ifTrue:[
+ result sign:sign
+ ]
].
ok := false.
@@ -1192,180 +1194,180 @@
if (__isSmallInteger(len)
&& __isByteArray(__digitByteArray)
&& __isByteArray(resultDigitByteArray)) {
- INT _l = __intVal(len);
- INT _v = __intVal(val);
- unsigned INT _carry = 0;
- unsigned INT _prod;
- unsigned char *digitP = __ByteArrayInstPtr(__digitByteArray)->ba_element;
- unsigned char *resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+ INT _l = __intVal(len);
+ INT _v = __intVal(val);
+ unsigned INT _carry = 0;
+ unsigned INT _prod;
+ unsigned char *digitP = __ByteArrayInstPtr(__digitByteArray)->ba_element;
+ unsigned char *resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
- /*
- * skipping zeros does not help much (a few percent) on
- * a P5 or other CPUS with a fast multiplier.
- * It may make more of a difference on CPUs with slower 0-multiply.
- */
- while ((_l >= sizeof(INT)) && (((unsigned INT *)digitP)[0] == 0)) {
- ((unsigned long *)resultP)[0] = 0;
- digitP += sizeof(INT);
- resultP += sizeof(INT);
- _l -= sizeof(INT);
- }
+ /*
+ * skipping zeros does not help much (a few percent) on
+ * a P5 or other CPUS with a fast multiplier.
+ * It may make more of a difference on CPUs with slower 0-multiply.
+ */
+ while ((_l >= sizeof(INT)) && (((unsigned INT *)digitP)[0] == 0)) {
+ ((unsigned long *)resultP)[0] = 0;
+ digitP += sizeof(INT);
+ resultP += sizeof(INT);
+ _l -= sizeof(INT);
+ }
#if defined(i386) || defined(alpha) /* XXX actually: LSB_FIRST */
# if defined (__GNUC__) && defined(i386)
- /*
- * can do it long-word-wise;
- * 32*32 -> 64 multiplication
- */
- while (_l > 3) {
- unsigned __pHi, __pLow;
+ /*
+ * can do it long-word-wise;
+ * 32*32 -> 64 multiplication
+ */
+ while (_l > 3) {
+ unsigned __pHi, __pLow;
- /*
- * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
- * + maxCarry (0xFFFF.FFFF) -> 0xFFFF.FFFF.0000.0000
- */
- asm ("mull %3 \n
- addl %4,%%eax \n
- adcl $0,%%edx"
- : "=a" ((unsigned long)(__pLow)),
- "=d" ((unsigned long)(__pHi))
- : "0" ((unsigned long)(((unsigned long *)digitP)[0])),
- "1" ((unsigned long)(_v)),
- "rm" ((unsigned long)(_carry)) );
+ /*
+ * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
+ * + maxCarry (0xFFFF.FFFF) -> 0xFFFF.FFFF.0000.0000
+ */
+ asm ("mull %3 \n
+ addl %4,%%eax \n
+ adcl $0,%%edx"
+ : "=a" ((unsigned long)(__pLow)),
+ "=d" ((unsigned long)(__pHi))
+ : "0" ((unsigned long)(((unsigned long *)digitP)[0])),
+ "1" ((unsigned long)(_v)),
+ "rm" ((unsigned long)(_carry)) );
- ((unsigned long *)resultP)[0] = __pLow;
- _carry = __pHi;
- digitP += 4;
- resultP += 4;
- _l -= 4;
- }
+ ((unsigned long *)resultP)[0] = __pLow;
+ _carry = __pHi;
+ digitP += 4;
+ resultP += 4;
+ _l -= 4;
+ }
# else
# if defined(INT64)
- if (_v <= 0xFFFFFFFFL) {
- /*
- * have a 64bit int type ... good
- */
- UINT64 _prod64;
+ if (_v <= 0xFFFFFFFFL) {
+ /*
+ * have a 64bit int type ... good
+ */
+ UINT64 _prod64;
- /* have 64bit ints; can do it int-wise
- *
- * max: 0xFFFFFFFF * 0xFFFFFFFF -> 0xFFFFFFFE.0001
- * + maxCarry (0xFFFFFFFF) -> 0xFFFFFFFF.0000
- */
- while (_l > 3) {
- unsigned __t;
+ /* have 64bit ints; can do it int-wise
+ *
+ * max: 0xFFFFFFFF * 0xFFFFFFFF -> 0xFFFFFFFE.0001
+ * + maxCarry (0xFFFFFFFF) -> 0xFFFFFFFF.0000
+ */
+ while (_l > 3) {
+ unsigned __t;
- __t = ((unsigned *)digitP)[0];
- digitP += 4;
- _prod64 = (INT64)_v;
- _prod64 *= __t;
- _prod64 += _carry;
- ((unsigned *)resultP)[0] = _prod64 /* & 0xFFFFFFFFL */;
- _carry = _prod64 >> 32;
- resultP += 4;
- _l -= 4;
- }
- if (_l > 1) {
- unsigned short __t;
+ __t = ((unsigned *)digitP)[0];
+ digitP += 4;
+ _prod64 = (INT64)_v;
+ _prod64 *= __t;
+ _prod64 += _carry;
+ ((unsigned *)resultP)[0] = _prod64 /* & 0xFFFFFFFFL */;
+ _carry = _prod64 >> 32;
+ resultP += 4;
+ _l -= 4;
+ }
+ if (_l > 1) {
+ unsigned short __t;
- __t = ((unsigned short *)digitP)[0];
- digitP += 2;
- _prod64 = (INT64)_v;
- _prod64 *= __t;
- _prod64 += _carry;
- ((unsigned short *)resultP)[0] = _prod64 /* & 0xFFFF */;
- _carry = _prod64 >> 16;
- resultP += 2;
- _l -= 2;
- }
- if (_l > 0) {
- _prod64 = *digitP++ * _v + _carry;
- *resultP++ = _prod64 /* & 0xFF */;
- _carry = _prod64 >> 8;
- _l--;
- }
- }
+ __t = ((unsigned short *)digitP)[0];
+ digitP += 2;
+ _prod64 = (INT64)_v;
+ _prod64 *= __t;
+ _prod64 += _carry;
+ ((unsigned short *)resultP)[0] = _prod64 /* & 0xFFFF */;
+ _carry = _prod64 >> 16;
+ resultP += 2;
+ _l -= 2;
+ }
+ if (_l > 0) {
+ _prod64 = *digitP++ * _v + _carry;
+ *resultP++ = _prod64 /* & 0xFF */;
+ _carry = _prod64 >> 8;
+ _l--;
+ }
+ }
# else
- if (_v <= 0xFFFF) {
- /* can do it short-wise
- *
- * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
- * + maxCarry (0xFFFF) -> 0xFFFF.0000
- */
- while (_l > 1) {
- _prod = ((unsigned short *)digitP)[0] * _v + _carry;
- ((unsigned short *)resultP)[0] = _prod /* & 0xFFFF */;
- _carry = _prod >> 16;
- digitP += 2;
- resultP += 2;
- _l -= 2;
- }
- }
+ if (_v <= 0xFFFF) {
+ /* can do it short-wise
+ *
+ * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
+ * + maxCarry (0xFFFF) -> 0xFFFF.0000
+ */
+ while (_l > 1) {
+ _prod = ((unsigned short *)digitP)[0] * _v + _carry;
+ ((unsigned short *)resultP)[0] = _prod /* & 0xFFFF */;
+ _carry = _prod >> 16;
+ digitP += 2;
+ resultP += 2;
+ _l -= 2;
+ }
+ }
# endif /* no INT64 */
# endif /* not GNU-i386 */
#else /* not LSB_FIRST */
- if (_v <= 0xFFFF) {
- /* can do it short-wise
- *
- * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
- * + maxCarry (0xFFFF) -> 0xFFFF.0000
- */
- while (_l > 1) {
- unsigned int t;
+ if (_v <= 0xFFFF) {
+ /* can do it short-wise
+ *
+ * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
+ * + maxCarry (0xFFFF) -> 0xFFFF.0000
+ */
+ while (_l > 1) {
+ unsigned int t;
- t = (digitP[1]<<8) + digitP[0];
- _prod = t * _v + _carry;
- resultP[0] = _prod /* & 0xFF */;
- resultP[1] = (_prod>>8) /* & 0xFF */;
- _carry = _prod >> 16;
- digitP += 2;
- resultP += 2;
- _l -= 2;
- }
- }
+ t = (digitP[1]<<8) + digitP[0];
+ _prod = t * _v + _carry;
+ resultP[0] = _prod /* & 0xFF */;
+ resultP[1] = (_prod>>8) /* & 0xFF */;
+ _carry = _prod >> 16;
+ digitP += 2;
+ resultP += 2;
+ _l -= 2;
+ }
+ }
#endif /* LSB_FIRST */
- /*
- * rest is done byte-wise
- */
- while (_l > 0) {
- _prod = *digitP++ * _v + _carry;
- *resultP++ = _prod /* & 0xFF */;
- _carry = _prod >> 8;
- _l--;
- }
+ /*
+ * rest is done byte-wise
+ */
+ while (_l > 0) {
+ _prod = *digitP++ * _v + _carry;
+ *resultP++ = _prod /* & 0xFF */;
+ _carry = _prod >> 8;
+ _l--;
+ }
- _l = __intVal(lResult) - __intVal(len);
+ _l = __intVal(lResult) - __intVal(len);
- /*
- * remaining carry
- */
- while (_carry) {
- *resultP++ = _carry & 0xFF;
- _carry >>= 8;
- _l--;
- }
+ /*
+ * remaining carry
+ */
+ while (_carry) {
+ *resultP++ = _carry & 0xFF;
+ _carry >>= 8;
+ _l--;
+ }
- /*
- * remaining zeros
- */
- while (_l--) {
- *resultP++ = 0;
- }
+ /*
+ * remaining zeros
+ */
+ while (_l--) {
+ *resultP++ = 0;
+ }
- /*
- * need compress ?
- */
- if (resultP[-1]) {
- /*
- * no
- */
- RETURN(result);
- }
+ /*
+ * need compress ?
+ */
+ if (resultP[-1]) {
+ /*
+ * no
+ */
+ RETURN(result);
+ }
- ok = true;
+ ok = true;
}
%}.
"
@@ -1373,21 +1375,21 @@
(could make it a primitive-failure as well)
"
ok ifFalse:[
- carry := 0.
- 1 to:len do:[:i |
- prod := (digitByteArray basicAt:i) * val + carry.
- resultDigitByteArray basicAt:i put:(prod bitAnd:16rFF).
- carry := prod bitShift:-8.
- ].
- [carry ~~ 0] whileTrue:[
- len := len + 1.
- resultDigitByteArray basicAt:len put:(carry bitAnd:16rFF).
- carry := carry bitShift:-8
- ].
- [len < lResult] whileTrue:[
- len := len + 1.
- resultDigitByteArray basicAt:len put:0
- ]
+ carry := 0.
+ 1 to:len do:[:i |
+ prod := (digitByteArray basicAt:i) * val + carry.
+ resultDigitByteArray basicAt:i put:(prod bitAnd:16rFF).
+ carry := prod bitShift:-8.
+ ].
+ [carry ~~ 0] whileTrue:[
+ len := len + 1.
+ resultDigitByteArray basicAt:len put:(carry bitAnd:16rFF).
+ carry := carry bitShift:-8
+ ].
+ [len < lResult] whileTrue:[
+ len := len + 1.
+ resultDigitByteArray basicAt:len put:0
+ ]
].
^ result compressed
!
@@ -1397,18 +1399,19 @@
Return the sum of the receiver and the argument, (which must be a SmallInteger)"
anInteger > 0 ifTrue:[
- sign < 0 ifTrue:[
- ^ (self absFastMinus:anInteger) sign:-1
+ sign > 0 ifTrue:[
+ ^ self absFastPlus:anInteger
].
- ^ self absFastPlus:anInteger
+ ^ (self absFastMinus:anInteger) sign:-1
].
anInteger == 0 ifTrue:[
^ self
].
- sign < 0 ifTrue:[
- ^ (self absFastPlus:anInteger abs) sign:-1
+ sign > 0 ifTrue:[
+ ^ self absFastMinus:anInteger
].
- ^ self absFastMinus:anInteger
+ ^ (self absFastPlus:anInteger abs) sign:-1
+
"
12345678901234567890
@@ -1421,7 +1424,7 @@
-12345678901234567890 sumFromInteger:-1
"
- "Modified: 20.10.1996 / 18:41:51 / cg"
+ "Modified: / 9.1.1998 / 13:27:37 / cg"
! !
!LargeInteger methodsFor:'printing & storing'!
@@ -1572,7 +1575,7 @@
#ifdef i386
if (divisor < 0xFFFF) {
if ((index & 1) == 0) { /* even number of bytes */
- while (index > 1) {
+ while (index > 1) {
unsigned INT t;
unsigned INT div;
@@ -1655,30 +1658,30 @@
borrow := aSmallInteger abs.
[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) 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 <= rsltLen) ifTrue:[
- [index <= len] whileTrue:[
- resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index).
- index := index + 1
- ].
- lastDigit := 0.
+ [index <= len] whileTrue:[
+ resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index).
+ index := index + 1
+ ].
+ lastDigit := 0.
].
lastDigit == 0 ifTrue:[
- ^ result compressed
+ ^ result compressed
].
^ result
@@ -1735,12 +1738,12 @@
}
if (__index <= __intVal(rsltLen)) {
while (__index <= __len) {
- __dst[__index-1] = __src[__index-1];
- __index++;
+ __dst[__index-1] = __src[__index-1];
+ __index++;
}
__lastDigit = 0;
}
- if (lastDigit) {
+ if (lastDigit) {
RETURN (result);
}
ok = true;
@@ -1748,29 +1751,29 @@
%}.
ok ~~ true ifTrue:[
- index := 1.
- carry := aSmallInteger abs.
+ 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
- ].
+ [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.
- ].
+ (index <= rsltLen) ifTrue:[
+ [index <= len] whileTrue:[
+ resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index).
+ index := index + 1
+ ].
+ lastDigit := 0.
+ ].
- lastDigit ~~ 0 ifTrue:[
- ^ result
- ].
+ lastDigit ~~ 0 ifTrue:[
+ ^ result
+ ].
].
^ result compressed
@@ -1999,62 +2002,62 @@
if (__isByteArray(_digitByteArray)
&& __isByteArray(otherDigitByteArray)) {
- int _len1, _len2, _newLen;
- unsigned char *_myDigits, *_otherDigits, *_newDigits;
- int _index, _carry;
- int _comLen;
+ int _len1, _len2, _newLen;
+ unsigned char *_myDigits, *_otherDigits, *_newDigits;
+ int _index, _carry;
+ int _comLen;
- _len1 = __byteArraySize(_digitByteArray);
- _len2 = __byteArraySize(otherDigitByteArray);
+ _len1 = __byteArraySize(_digitByteArray);
+ _len2 = __byteArraySize(otherDigitByteArray);
- _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
- _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+ _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 (_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);
+ }
+ _comLen = _len1;
+ }
+ resultDigitByteArray = __BYTEARRAY_UNINITIALIZED_NEW_INT(_newLen);
- /*
- * must refetch - GC could have been invoked
- */
- _digitByteArray = __INST(digitByteArray);
+ /*
+ * 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;
+ _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+ _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+ _newDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
- /*
- * add them ...
- */
- _index = 1;
- _carry = 0;
+ /*
+ * add them ...
+ */
+ _index = 1;
+ _carry = 0;
#if defined(i386) || defined(alpha) /* actually: LSB first */
# ifdef INT64
@@ -2062,137 +2065,137 @@
* have a 64bit integer type;
* add long-wise
*/
- while (_index < _comLen) {
- UINT64 _sum;
+ while (_index < _comLen) {
+ UINT64 _sum;
- _sum = _carry;
- _sum += *(unsigned *)(&(_myDigits[_index - 1]));
- _sum += *(unsigned *)(&(_otherDigits[_index - 1]));
+ _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;
- }
+ *(unsigned *)(&(_newDigits[_index - 1])) = _sum;
+ _index += 4;
+ }
# endif
- /*
- * add short-wise
- */
- while (_index < _comLen) {
- unsigned int _sum;
+ /*
+ * add short-wise
+ */
+ while (_index < _comLen) {
+ unsigned int _sum;
- _sum = _carry;
- _sum += *(unsigned short *)(&(_myDigits[_index - 1]));
- _sum += *(unsigned short *)(&(_otherDigits[_index - 1]));
+ _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;
- }
+ *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
+ _index += 2;
+ }
#endif
- /*
- * add byte
- */
- while (_index <= _comLen) {
- unsigned int _sum;
+ /*
+ * add byte
+ */
+ while (_index <= _comLen) {
+ unsigned int _sum;
- _sum = _carry;
- _sum += _myDigits[_index - 1];
- _sum += _otherDigits[_index - 1];
+ _sum = _carry;
+ _sum += _myDigits[_index - 1];
+ _sum += _otherDigits[_index - 1];
_carry = _sum >> 8;
_sum = _sum & 0xFF;
- _newDigits[_index - 1] = _sum;
- _index++;
- }
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
- /*
- * rest
- */
- while (_index <= _newLen) {
- unsigned int _sum;
+ /*
+ * 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];
- }
- }
+ _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++;
- }
+ _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.
+ 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.
+ "/ 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.
- ]
- ].
+ 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.
+ result := self class basicNew numberOfDigits:newLen.
+ resultDigitByteArray := result digits.
- index := 1.
- carry := 0.
+ 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
- ].
+ 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
@@ -2284,9 +2287,9 @@
#if defined(i386) /* XXX actually: LSB_FIRST */
if (sizeof(unsigned int) == 4) {
if ((__idx + 4) < __nBytes) {
- __this = ((unsigned int *)__bp)[0];
+ __this = ((unsigned int *)__bp)[0];
- while ((__idx + 4) < __nBytes) {
+ while ((__idx + 4) < __nBytes) {
__next = ((unsigned int *)__bp)[1];
__this = (__this >> 1) /* & 0x7FFFFFF */;
__this |= __next << 31;
@@ -2294,7 +2297,7 @@
__this = __next;
__bp += 4;
__idx += 4;
- }
+ }
}
}
#endif
@@ -2355,12 +2358,12 @@
#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;
+ __this = ((unsigned int *)__bp)[0];
+ __newCarry = (__this >> 31) /* & 1 */;
+ ((unsigned int *)__bp)[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp += 4;
+ __nBytes -= 4;
}
}
#endif
@@ -2454,5 +2457,5 @@
!LargeInteger class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.61 1997-11-26 21:35:43 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.62 1998-01-12 13:18:47 cg Exp $'
! !