--- a/LargeInteger.st Wed May 20 18:01:16 2015 +0200
+++ b/LargeInteger.st Wed May 20 18:01:28 2015 +0200
@@ -271,6 +271,21 @@
"
!
+digitBytes:aByteArrayOfDigits sign:sign
+ "create and return a new LargeInteger with digits (lsb-first)
+ from the argument, aByteArray.
+ Experimental interface - May change/be removed without notice."
+
+ ^ self basicNew setDigits:aByteArrayOfDigits sign:sign
+
+ "
+ LargeInteger digitBytes:#[16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF]
+ (LargeInteger digitBytes:#[16r12 16r34 16r56 16r78 16r90]) hexPrintString
+ "
+
+ "Modified: / 8.5.1998 / 21:40:41 / cg"
+!
+
new
"catch creation message.
LargeIntegers are only created by system code, which
@@ -326,20 +341,20 @@
Use a special method for this case ...
"
((numberClass := aNumber class) == SmallInteger) ifTrue:[
- ^ self productFromInteger:aNumber
+ ^ self productFromInteger:aNumber
].
"
if the argument is not a largeInteger, coerce
"
(numberClass == self class) ifFalse:[
- ^ self retry:#* coercing:aNumber
+ ^ self retry:#* coercing:aNumber
].
otherSign := aNumber sign.
(sign == otherSign) ifTrue:[^ self absMul:aNumber].
(otherSign == 0) ifTrue:[^ 0].
- ^ (self absMul:aNumber) sign:-1
+ ^ (self absMul:aNumber) setSign:-1
!
+ aNumber
@@ -483,12 +498,12 @@
The result is truncated toward negative infinity
and will be negative, if the operands signs differ.
The following is always true:
- (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
+ (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
Especially surprising:
- -1 // 10 -> -1 (because -(1/10) is truncated towards next smaller integer, which is -1.
- -10 // 3 -> -4 (because -(10/3) is truncated towards next smaller integer, which is -4.
+ -1 // 10 -> -1 (because -(1/10) is truncated towards next smaller integer, which is -1.
+ -10 // 3 -> -4 (because -(10/3) is truncated towards next smaller integer, which is -4.
See #quo: which returns -2 in the above case and #rem: which is the corresponding remainder."
@@ -502,38 +517,38 @@
Use a special method for this case ...
"
(cls == SmallInteger) ifTrue:[
- abs := aNumber.
- abs := abs abs.
- (abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
- divMod := self absFastDivMod:abs.
- ] ifFalse:[
- n := abs asLargeInteger.
- ].
+ abs := aNumber.
+ abs := abs abs.
+ (abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse: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 ...
- "/ be careful: there is one special case to care for here:
- "/ if quo is maxInt+1, the negation can be represented as a smallInt.
- quo := quo sign:-1.
- (divMod at:2) == 0 ifFalse:[
- ^ quo - 1
- ].
- quo digitLength == SmallInteger maxBytes ifTrue:[
- ^ quo compressed
- ].
+ "/ adjust for truncation if negative and there is a remainder ...
+ "/ be careful: there is one special case to care for here:
+ "/ if quo is maxInt+1, the negation can be represented as a smallInt.
+ quo := quo setSign:-1.
+ (divMod at:2) == 0 ifFalse:[
+ ^ quo - 1
+ ].
+ quo digitLength == SmallInteger maxBytes ifTrue:[
+ ^ quo compressed
+ ].
].
^ quo
@@ -571,14 +586,14 @@
The returned remainder has the same sign as aNumber.
The following is always true:
- (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
+ (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
Especially surprising:
- -1 \\ 10 -> 9 (because -(1/10) is truncated towards next smaller integer, which is -1,
- and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
- -10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
- and -4 * 4 gives -12, so we need to add 2 to get the original -10.
+ -1 \\ 10 -> 9 (because -(1/10) is truncated towards next smaller integer, which is -1,
+ and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
+ -10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
+ and -4 * 4 gives -12, so we need to add 2 to get the original -10.
See #rem: which is the corresponding remainder for division via #quo:.
@@ -587,11 +602,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.
].
"
@@ -599,33 +614,33 @@
Use a special method for this case ...
"
(aNumber class == SmallInteger) ifTrue:[
- (abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
- rem := (self absFastDivMod:abs) at:2.
- ] ifFalse:[
- rem := self absMod:abs asLargeInteger
- ].
+ (abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse: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 setSign:-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
@@ -732,43 +747,43 @@
special case for SmallInteger minVal
"
sign == 1 ifTrue:[
- sz := digitByteArray size.
+ sz := digitByteArray size.
%{
- int idx;
- unsigned char *bp;
-
- bp = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
- idx = __intVal(sz);
-
- while ((idx > 1) && (bp[idx-1] == 0)) idx--;
-
- if (idx == sizeof(INT)) {
+ int idx;
+ unsigned char *bp;
+
+ bp = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
+ idx = __intVal(sz);
+
+ while ((idx > 1) && (bp[idx-1] == 0)) idx--;
+
+ if (idx == sizeof(INT)) {
#if defined(__LSBFIRST__)
# if __POINTER_SIZE__ == 8
- if ( ((unsigned INT *)bp)[0] == 0x4000000000000000L)
+ if ( ((unsigned INT *)bp)[0] == 0x4000000000000000L)
# else
- if ( ((unsigned INT *)bp)[0] == 0x40000000)
+ if ( ((unsigned INT *)bp)[0] == 0x40000000)
# endif
#else
- /*
- * generic code
- */
- if ((bp[idx-1] == 0x40)
- && (bp[idx-2] == 0)
- && (bp[idx-3] == 0)
- && (bp[idx-4] == 0)
+ /*
+ * generic code
+ */
+ if ((bp[idx-1] == 0x40)
+ && (bp[idx-2] == 0)
+ && (bp[idx-3] == 0)
+ && (bp[idx-4] == 0)
# if __POINTER_SIZE__ == 8
- && (bp[idx-5] == 0)
- && (bp[idx-6] == 0)
- && (bp[idx-7] == 0)
- && (bp[idx-8] == 0)
+ && (bp[idx-5] == 0)
+ && (bp[idx-6] == 0)
+ && (bp[idx-7] == 0)
+ && (bp[idx-8] == 0)
# endif
- )
+ )
#endif
- {
- RETURN (__mkSmallInteger(_MIN_INT));
- }
- }
+ {
+ RETURN (__mkSmallInteger(_MIN_INT));
+ }
+ }
%}.
"/ sz == 4 ifTrue:[
"/ (digitByteArray at:1) == 0 ifTrue:[
@@ -783,8 +798,7 @@
"/ ]
].
"/ cg - can share the digits ...
- newNumber := self class digitBytes:digitByteArray.
- newNumber sign:(sign negated).
+ newNumber := self class digitBytes:digitByteArray sign:(sign negated).
^ newNumber
!
@@ -795,7 +809,7 @@
The results sign is negative if the receiver has a sign
different from the args sign.
The following is always true:
- (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
+ (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
"
|otherSign quo abs "{ Class: SmallInteger }" |
@@ -807,28 +821,28 @@
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 setSign:-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
+ ^ ((self absDivMod:aNumber) at:1) setSign:-1
"
900 // 400
@@ -860,7 +874,7 @@
"return the remainder of division of the receiver by the argument, aNumber.
The returned remainder has the same sign as the receiver.
The following is always true:
- (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
+ (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
"
|rem abs "{ Class: SmallInteger }" |
@@ -870,26 +884,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 setSign:-1
].
^ rem
@@ -1313,24 +1327,24 @@
|myDigitLength newDigitLength newDigitBytes byteIndexOfBitToSet|
index <= 0 ifTrue:[
- ^ SubscriptOutOfBoundsSignal
- raiseRequestWith:index
- errorString:'index out of bounds'
+ ^ SubscriptOutOfBoundsSignal
+ raiseRequestWith:index
+ errorString:'index out of bounds'
].
myDigitLength := digitByteArray size.
byteIndexOfBitToSet := ((index-1)//8)+1.
byteIndexOfBitToSet > myDigitLength ifTrue:[
- newDigitLength := myDigitLength max:byteIndexOfBitToSet.
- newDigitBytes := ByteArray new:newDigitLength.
- newDigitBytes replaceFrom:1 to:myDigitLength with:digitByteArray startingAt:1.
+ newDigitLength := myDigitLength max:byteIndexOfBitToSet.
+ newDigitBytes := ByteArray new:newDigitLength.
+ newDigitBytes replaceFrom:1 to:myDigitLength with:digitByteArray startingAt:1.
] ifFalse:[
- newDigitBytes := digitByteArray copy
+ newDigitBytes := digitByteArray copy
].
newDigitBytes
- at:byteIndexOfBitToSet
- put:((newDigitBytes at:byteIndexOfBitToSet) setBit:(((index-1)\\8)+1)).
- ^ (self class digitBytes:newDigitBytes) sign:sign
+ at:byteIndexOfBitToSet
+ put:((newDigitBytes at:byteIndexOfBitToSet) setBit:(((index-1)\\8)+1)).
+ ^ self class digitBytes:newDigitBytes sign:sign
"
TestCase assert:( 16r80000000 setBit:3 ) = 16r80000004
@@ -1585,19 +1599,19 @@
#endif
%}.
sign >= 0 ifTrue:[
- index > digitByteArray size ifTrue:[
- ^ 0
- ].
- ^ digitByteArray at:index.
+ index > digitByteArray size ifTrue:[
+ ^ 0
+ ].
+ ^ digitByteArray at:index.
].
"/ negative int - do 2's complement here
t := self bitInvert + 1.
- t sign:1.
+ t setSign:1.
digits := t digitBytes.
index > digits size ifTrue:[
- ^ 16rFF
+ ^ 16rFF
].
^ digits at:index.
@@ -2346,38 +2360,38 @@
num := anInteger abs.
(num > 16r3FFFFF) ifTrue:[
- "if num is too big (so that multiplying by a byte could create a Large)"
-
- ^ anInteger retry:#* coercing:self
+ "if num is too big (so that multiplying by a byte could create a Large)"
+
+ ^ 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 setSign:-1
+ ].
] ifFalse:[
- sign < 0 ifTrue:[
- result sign:sign
- ]
+ sign < 0 ifTrue:[
+ result setSign:sign
+ ]
].
ok := false.
@@ -2387,156 +2401,156 @@
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;
-
- /*
- * 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 INT *)resultP)[0] = 0;
- digitP += sizeof(INT);
- resultP += sizeof(INT);
- _l -= sizeof(INT);
- }
+ 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 INT *)resultP)[0] = 0;
+ digitP += sizeof(INT);
+ resultP += sizeof(INT);
+ _l -= sizeof(INT);
+ }
#if defined(__LSBFIRST__)
# if defined (__GNUC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
- /*
- * can do it long-word-wise;
- * 32*32 -> 64 multiplication
- */
- while (_l > 3) {
- unsigned __pHi, __pLow;
- unsigned __digit;
-
- /*
- * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
- * + maxCarry (0xFFFF.FFFF) -> 0xFFFF.FFFF.0000.0000
- */
- __digit = ((unsigned long *)digitP)[0];
- asm ("mull %3 \n\
- addl %4,%%eax \n\
- adcl $0,%%edx"
- : "=a" (__pLow),
- "=d" (__pHi)
- : "0" (__digit),
- "1" ((unsigned long)(_v)),
- "rm" ((unsigned long)(_carry)) );
-
- ((unsigned long *)resultP)[0] = __pLow;
- _carry = __pHi;
- digitP += 4;
- resultP += 4;
- _l -= 4;
- }
+ /*
+ * can do it long-word-wise;
+ * 32*32 -> 64 multiplication
+ */
+ while (_l > 3) {
+ unsigned __pHi, __pLow;
+ unsigned __digit;
+
+ /*
+ * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
+ * + maxCarry (0xFFFF.FFFF) -> 0xFFFF.FFFF.0000.0000
+ */
+ __digit = ((unsigned long *)digitP)[0];
+ asm ("mull %3 \n\
+ addl %4,%%eax \n\
+ adcl $0,%%edx"
+ : "=a" (__pLow),
+ "=d" (__pHi)
+ : "0" (__digit),
+ "1" ((unsigned long)(_v)),
+ "rm" ((unsigned long)(_carry)) );
+
+ ((unsigned long *)resultP)[0] = __pLow;
+ _carry = __pHi;
+ digitP += 4;
+ resultP += 4;
+ _l -= 4;
+ }
# else /* not GNU-i386 */
# if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
- /*
- * can do it long-word-wise;
- * 32*32 -> 64 multiplication
- */
- while (_l > 3) {
- unsigned __pLow;
- unsigned digit;
-
- /*
- * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
- * + maxCarry (0xFFFF.FFFF) -> 0xFFFF.FFFF.0000.0000
- */
+ /*
+ * can do it long-word-wise;
+ * 32*32 -> 64 multiplication
+ */
+ while (_l > 3) {
+ unsigned __pLow;
+ unsigned digit;
+
+ /*
+ * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
+ * + maxCarry (0xFFFF.FFFF) -> 0xFFFF.FFFF.0000.0000
+ */
/*
- digit = ((unsigned long *)digitP)[0];
- edx::eax = (digit * _v);
- edx::eax += _carry;
- ((unsigned long *)resultP)[0] = eax; -- pLow
- _carry = edx; -- pHigh
- digitP += 4;
- resultP += 4;
+ digit = ((unsigned long *)digitP)[0];
+ edx::eax = (digit * _v);
+ edx::eax += _carry;
+ ((unsigned long *)resultP)[0] = eax; -- pLow
+ _carry = edx; -- pHigh
+ digitP += 4;
+ resultP += 4;
*/
- digit = ((unsigned long *)digitP)[0];
- asm {
- mov eax, digit
- mov edx, _v
- mul edx
- add eax, _carry
- adc edx, 0
- mov __pLow, eax
- mov _carry, edx
- }
-
- ((unsigned long *)resultP)[0] = __pLow;
- digitP += 4;
- resultP += 4;
- _l -= 4;
- }
+ digit = ((unsigned long *)digitP)[0];
+ asm {
+ mov eax, digit
+ mov edx, _v
+ mul edx
+ add eax, _carry
+ adc edx, 0
+ mov __pLow, eax
+ mov _carry, edx
+ }
+
+ ((unsigned long *)resultP)[0] = __pLow;
+ digitP += 4;
+ resultP += 4;
+ _l -= 4;
+ }
# else /* not WIN32-i386 */
# if defined(INT64)
- 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;
-
- __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--;
- }
- }
+ 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;
+
+ __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--;
+ }
+ }
# else /* no INT64 type */
- 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 WIN32-i386 */
# endif /* not GNU-i386 */
@@ -2547,80 +2561,80 @@
/* no, STORE_WORD_WISE makes it slower */
# endif
- 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;
#if defined(LOAD_WORD_WISE)
- /* better fetch short-wise */
- t = ((unsigned short *)digitP)[0];
- digitP += 2;
- t = ((t >> 8) | (t << 8)) & 0xFFFF;
+ /* better fetch short-wise */
+ t = ((unsigned short *)digitP)[0];
+ digitP += 2;
+ t = ((t >> 8) | (t << 8)) & 0xFFFF;
#else
- t = (digitP[1]<<8) + digitP[0];
- digitP += 2;
+ t = (digitP[1]<<8) + digitP[0];
+ digitP += 2;
#endif
- _prod = t * _v + _carry;
- _carry = _prod >> 16;
+ _prod = t * _v + _carry;
+ _carry = _prod >> 16;
#if defined(STORE_WORD_WISE)
- /* better store short-wise */
- _prod = ((_prod >> 8) | (_prod << 8)) & 0xFFFF;
- ((unsigned short *)resultP)[0] = _prod;
+ /* better store short-wise */
+ _prod = ((_prod >> 8) | (_prod << 8)) & 0xFFFF;
+ ((unsigned short *)resultP)[0] = _prod;
#else
- resultP[0] = _prod /* & 0xFF */;
- resultP[1] = (_prod>>8) /* & 0xFF */;
+ resultP[0] = _prod /* & 0xFF */;
+ resultP[1] = (_prod>>8) /* & 0xFF */;
#endif
- resultP += 2;
- _l -= 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--;
- }
-
- _l = __intVal(lResult) - __intVal(len);
-
- /*
- * remaining carry
- */
- while (_carry) {
- *resultP++ = _carry /* & 0xFF */;
- _carry >>= 8;
- _l--;
- }
-
- /*
- * remaining zeros
- */
- while (_l--) {
- *resultP++ = 0;
- }
-
- /*
- * need compress ?
- */
- if (resultP[-1]) {
- /*
- * no
- */
- RETURN(result);
- }
-
- ok = true;
+ /*
+ * rest is done byte-wise
+ */
+ while (_l > 0) {
+ _prod = *digitP++ * _v + _carry;
+ *resultP++ = _prod /* & 0xFF */;
+ _carry = _prod >> 8;
+ _l--;
+ }
+
+ _l = __intVal(lResult) - __intVal(len);
+
+ /*
+ * remaining carry
+ */
+ while (_carry) {
+ *resultP++ = _carry /* & 0xFF */;
+ _carry >>= 8;
+ _l--;
+ }
+
+ /*
+ * remaining zeros
+ */
+ while (_l--) {
+ *resultP++ = 0;
+ }
+
+ /*
+ * need compress ?
+ */
+ if (resultP[-1]) {
+ /*
+ * no
+ */
+ RETURN(result);
+ }
+
+ ok = true;
}
%}.
"
@@ -2628,21 +2642,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
!
@@ -3047,14 +3061,13 @@
((aSmallInteger < (SmallInteger minVal + 255))
or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
- ^ self absMinus:(self class value:aSmallInteger) sign:newSign.
+ ^ self absMinus:(self class value:aSmallInteger) sign:newSign.
].
len := digitByteArray size.
rsltLen := len "+ 1".
- result := self class basicNew numberOfDigits:rsltLen.
- result sign:newSign.
+ result := self class basicNew numberOfDigits:rsltLen sign:newSign.
resultDigitByteArray := result digitBytes.
borrow := aSmallInteger abs.
@@ -3062,123 +3075,123 @@
%{
if (__isByteArray(__INST(digitByteArray))
&& __isByteArray(resultDigitByteArray)) {
- unsigned INT __borrow = __intVal(borrow);
- INT __diff;
- int __index = 1;
- int __len = __intVal(len);
- unsigned char *__digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
- unsigned char *__resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
- int __len3;
+ unsigned INT __borrow = __intVal(borrow);
+ INT __diff;
+ int __index = 1;
+ int __len = __intVal(len);
+ unsigned char *__digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
+ unsigned char *__resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+ int __len3;
#if defined(__LSBFIRST__)
# if (__POINTER_SIZE__ == 8)
- /*
- * subtract int-wise
- */
- __len3 = __len - 3;
- while (__index < __len3) {
- /* do not make this into one expression - ask cg why */
- __diff = ((unsigned int *)(__digitP + __index-1))[0];
- __diff -= (__borrow & 0xFFFFFFFFL);
- __borrow >>= 32;
- if (__diff < 0) {
- /* __diff += 0x100000000; */
- __borrow++;
- }
- ((unsigned int *)(__resultP+__index-1))[0] = __diff;
- __index += 4;
- }
+ /*
+ * subtract int-wise
+ */
+ __len3 = __len - 3;
+ while (__index < __len3) {
+ /* do not make this into one expression - ask cg why */
+ __diff = ((unsigned int *)(__digitP + __index-1))[0];
+ __diff -= (__borrow & 0xFFFFFFFFL);
+ __borrow >>= 32;
+ if (__diff < 0) {
+ /* __diff += 0x100000000; */
+ __borrow++;
+ }
+ ((unsigned int *)(__resultP+__index-1))[0] = __diff;
+ __index += 4;
+ }
# endif
- /*
- * subtract short-wise
- */
- while (__index < __len) {
- /* do not make this into one expression - ask cg why */
- __diff = ((unsigned short *)(__digitP+__index-1))[0];
- __diff -= (__borrow & 0xFFFF);
- __borrow >>= 16;
- if (__diff < 0) {
- /* __diff += 0x10000; */
- __borrow++;
- } else {
- if (__borrow == 0) {
- ((unsigned short *)(__resultP+__index-1))[0] = __diff;
- __index += 2;
-
- /* nothing more to subtract .. */
- while (__index < __len) {
- ((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0];
- __index += 2;
- }
- if (__index <= __len) {
- __resultP[__index-1] = __digitP[__index-1];
- }
- break;
- }
- }
- ((unsigned short *)(__resultP+__index-1))[0] = __diff;
- __index += 2;
- }
+ /*
+ * subtract short-wise
+ */
+ while (__index < __len) {
+ /* do not make this into one expression - ask cg why */
+ __diff = ((unsigned short *)(__digitP+__index-1))[0];
+ __diff -= (__borrow & 0xFFFF);
+ __borrow >>= 16;
+ if (__diff < 0) {
+ /* __diff += 0x10000; */
+ __borrow++;
+ } else {
+ if (__borrow == 0) {
+ ((unsigned short *)(__resultP+__index-1))[0] = __diff;
+ __index += 2;
+
+ /* nothing more to subtract .. */
+ while (__index < __len) {
+ ((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0];
+ __index += 2;
+ }
+ if (__index <= __len) {
+ __resultP[__index-1] = __digitP[__index-1];
+ }
+ break;
+ }
+ }
+ ((unsigned short *)(__resultP+__index-1))[0] = __diff;
+ __index += 2;
+ }
#endif
- /*
- * subtract byte-wise
- */
- while (__index <= __len) {
- __diff = __digitP[__index-1];
- __diff -= (__borrow & 0xFF);
- __borrow >>= 8;
- if (__diff < 0) {
- /* __diff += 0x100; */
- __borrow++;
- } else {
- if (__borrow == 0) {
- __resultP[__index-1] = __diff;
- __index++;
-
- /* nothing more to subtract .. */
- while (__index <= __len) {
- __resultP[__index-1] = __digitP[__index-1];
- __index++;
- }
- break;
- }
- }
- __resultP[__index-1] = __diff;
- __index++;
- }
- lastDigit = __mkSmallInteger( __resultP[__index-1-1] );
- ok = true;
+ /*
+ * subtract byte-wise
+ */
+ while (__index <= __len) {
+ __diff = __digitP[__index-1];
+ __diff -= (__borrow & 0xFF);
+ __borrow >>= 8;
+ if (__diff < 0) {
+ /* __diff += 0x100; */
+ __borrow++;
+ } else {
+ if (__borrow == 0) {
+ __resultP[__index-1] = __diff;
+ __index++;
+
+ /* nothing more to subtract .. */
+ while (__index <= __len) {
+ __resultP[__index-1] = __digitP[__index-1];
+ __index++;
+ }
+ break;
+ }
+ }
+ __resultP[__index-1] = __diff;
+ __index++;
+ }
+ lastDigit = __mkSmallInteger( __resultP[__index-1-1] );
+ ok = true;
}
%}.
ok == true ifFalse:[ "/ cannot happen
- index := 1.
- [borrow ~~ 0] whileTrue:[
- (index <= len) ifTrue:[
- diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF).
- borrow := borrow bitShift:-8.
- diff < 0 ifTrue:[
- diff := diff + 256.
- borrow := borrow + 1.
- ]
- ] ifFalse:[
- diff := borrow bitAnd:255.
- borrow := borrow bitShift:-8.
- ].
- resultDigitByteArray basicAt:index put:(lastDigit := diff).
- index := index + 1
- ].
- [index <= len] whileTrue:[
- resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index).
- index := index + 1
- ].
- (index <= rsltLen) ifTrue:[
- lastDigit := 0.
- ]
+ index := 1.
+ [borrow ~~ 0] whileTrue:[
+ (index <= len) ifTrue:[
+ diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF).
+ borrow := borrow bitShift:-8.
+ diff < 0 ifTrue:[
+ diff := diff + 256.
+ borrow := borrow + 1.
+ ]
+ ] ifFalse:[
+ diff := borrow bitAnd:255.
+ borrow := borrow bitShift:-8.
+ ].
+ resultDigitByteArray basicAt:index put:(lastDigit := diff).
+ index := index + 1
+ ].
+ [index <= len] whileTrue:[
+ resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index).
+ index := index + 1
+ ].
+ (index <= rsltLen) ifTrue:[
+ lastDigit := 0.
+ ]
].
(lastDigit == 0 or:[rsltLen <= SmallInteger maxBytes]) ifTrue:[
- ^ result compressed.
+ ^ result compressed.
].
^ result
@@ -3213,7 +3226,7 @@
((aSmallInteger < (SmallInteger minVal + 255))
or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
- ^ self absPlus:(self class value:aSmallInteger) sign:newSign.
+ ^ self absPlus:(self class value:aSmallInteger) sign:newSign.
].
len := rsltLen := digitByteArray size.
@@ -3222,331 +3235,330 @@
"/ if it is 255 (since the other number is definitely smaller)
"/
(digitByteArray at:len) == 16rFF ifTrue:[
- rsltLen := len + 1.
+ rsltLen := len + 1.
] ifFalse:[
- "/ or the argument has something in the high byte ..
+ "/ or the argument has something in the high byte ..
%{
#if __POINTER_SIZE__ == 8
- if (__intVal(aSmallInteger) & 0xFF00000000000000L) {
- rsltLen = __mkSmallInteger(__intVal(len) + 1);
- }
+ if (__intVal(aSmallInteger) & 0xFF00000000000000L) {
+ rsltLen = __mkSmallInteger(__intVal(len) + 1);
+ }
#else
- if (__intVal(aSmallInteger) & 0xFF000000) {
- rsltLen = __mkSmallInteger(__intVal(len) + 1);
- }
+ if (__intVal(aSmallInteger) & 0xFF000000) {
+ rsltLen = __mkSmallInteger(__intVal(len) + 1);
+ }
#endif
%}
].
- result := self class basicNew numberOfDigits:rsltLen.
- result sign:newSign.
+ result := self class basicNew numberOfDigits:rsltLen sign:newSign.
resultDigitByteArray := result digitBytes.
%{
if (__isByteArray(__INST(digitByteArray))
&& __isByteArray(resultDigitByteArray)
&& __isSmallInteger(aSmallInteger)) {
- /* carry is NOT unsigned (see negation below) */
- INT __carry = __intVal(aSmallInteger);
- int __index = 1;
- int __len = __intVal(len);
- unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
- unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element);
- INT __ptrDelta = __dst - __src;
- unsigned char *__srcLast = __src + __len - 1;
- int __rsltLen = __intVal(rsltLen);
-
- if (__carry < 0) {
- __carry = -__carry;
- }
+ /* carry is NOT unsigned (see negation below) */
+ INT __carry = __intVal(aSmallInteger);
+ int __index = 1;
+ int __len = __intVal(len);
+ unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
+ unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element);
+ INT __ptrDelta = __dst - __src;
+ unsigned char *__srcLast = __src + __len - 1;
+ int __rsltLen = __intVal(rsltLen);
+
+ if (__carry < 0) {
+ __carry = -__carry;
+ }
#if defined(__LSBFIRST__)
# if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4)
# if 0 /* NOTICE - the code below is 20% slower ... - why */
- /*
- * add long-wise
- */
- asm(" jecxz nothingToDo \n\
- movl %%eax, %%esi /* __src input */ \n\
- movl %%ebx, %%edi /* __dst input */ \n\
- \n\
- /* the first 4-byte int */ \n\
- lodsl /* fetch */ \n\
- addl %%edx, %%eax /* add */ \n\
- stosl /* store */ \n\
- leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\
- jecxz doneLoop /* any more ? */ \n\
- /* remaining 4-byte ints */ \n\
- jmp addLoop \n\
- \n\
- .align 8 \n\
- addLoop: \n\
- movl 0(%%esi), %%ebx /* fetch */ \n\
- jnc copyLoop2 \n\
- movl $0, %%eax \n\
- leal 4(%%esi), %%esi \n\
- adcl %%ebx, %%eax /* & add carry from prev int */\n\
- leal 8(%%edi), %%edi \n\
- movl %%eax, -8(%%edi) /* store */ \n\
- leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\
- jecxz doneLoop /* any more ? */ \n\
- \n\
- movl 0(%%esi), %%ebx /* fetch */ \n\
- movl $0, %%eax \n\
- leal 4(%%esi), %%esi \
- adcl %%ebx, %%eax /* & add carry from prev int */\n\
- movl %%eax, -4(%%edi) /* store */ \n\
- \n\
- loop addLoop \n\
- jmp doneLoop \n\
- \n\
- .align 8 \n\
- copyLoop: \n\
- movl 0(%%esi), %%ebx \n\
- copyLoop2: \n\
- add $4, %%esi \n\
- add $4, %%edi \n\
- movl %%ebx, -4(%%edi) \n\
- loop copyLoop \n\
- \n\
- doneLoop: \n\
- movl $0, %%edx /* do not clobber carry (xorl clears it) */ \n\
- adcl $0, %%edx \n\
- movl %%esi, %%eax /* __src output */ \n\
- nothingToDo: \n\
- " : "=d" ((unsigned long)(__carry)),
- "=a" (__src)
- : "1" (__src),
- "b" (__dst),
- "c" (__len / 4),
- "0" (__carry)
- : "esi", "edi");
+ /*
+ * add long-wise
+ */
+ asm(" jecxz nothingToDo \n\
+ movl %%eax, %%esi /* __src input */ \n\
+ movl %%ebx, %%edi /* __dst input */ \n\
+ \n\
+ /* the first 4-byte int */ \n\
+ lodsl /* fetch */ \n\
+ addl %%edx, %%eax /* add */ \n\
+ stosl /* store */ \n\
+ leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\
+ jecxz doneLoop /* any more ? */ \n\
+ /* remaining 4-byte ints */ \n\
+ jmp addLoop \n\
+ \n\
+ .align 8 \n\
+ addLoop: \n\
+ movl 0(%%esi), %%ebx /* fetch */ \n\
+ jnc copyLoop2 \n\
+ movl $0, %%eax \n\
+ leal 4(%%esi), %%esi \n\
+ adcl %%ebx, %%eax /* & add carry from prev int */\n\
+ leal 8(%%edi), %%edi \n\
+ movl %%eax, -8(%%edi) /* store */ \n\
+ leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\
+ jecxz doneLoop /* any more ? */ \n\
+ \n\
+ movl 0(%%esi), %%ebx /* fetch */ \n\
+ movl $0, %%eax \n\
+ leal 4(%%esi), %%esi \
+ adcl %%ebx, %%eax /* & add carry from prev int */\n\
+ movl %%eax, -4(%%edi) /* store */ \n\
+ \n\
+ loop addLoop \n\
+ jmp doneLoop \n\
+ \n\
+ .align 8 \n\
+ copyLoop: \n\
+ movl 0(%%esi), %%ebx \n\
+ copyLoop2: \n\
+ add $4, %%esi \n\
+ add $4, %%edi \n\
+ movl %%ebx, -4(%%edi) \n\
+ loop copyLoop \n\
+ \n\
+ doneLoop: \n\
+ movl $0, %%edx /* do not clobber carry (xorl clears it) */ \n\
+ adcl $0, %%edx \n\
+ movl %%esi, %%eax /* __src output */ \n\
+ nothingToDo: \n\
+ " : "=d" ((unsigned long)(__carry)),
+ "=a" (__src)
+ : "1" (__src),
+ "b" (__dst),
+ "c" (__len / 4),
+ "0" (__carry)
+ : "esi", "edi");
# else
- {
- unsigned char *__srcLastX;
-
- __srcLastX = __srcLast - 3 - 4;
- while (__src <= __srcLastX) {
- unsigned int __sum, __sum2;
- unsigned __digit1, __digit2;
-
- __digit1 = ((unsigned *)__src)[0];
- __digit2 = ((unsigned *)__src)[1];
- asm ("addl %%edx,%%ecx \n\
- adcl $0, %%eax \n\
- movl $0, %%edx \n\
- adcl $0, %%edx"
- : "=d" ((unsigned long)(__carry)),
- "=c" ((unsigned long)(__sum)),
- "=a" ((unsigned long)(__sum2))
- : "0" ((unsigned long)(__carry)),
- "1" (__digit1),
- "2" (__digit2));
-
- ((unsigned int *)(__src + __ptrDelta))[0] = __sum;
- ((unsigned int *)(__src + __ptrDelta))[1] = __sum2;
-
- __src += 8;
-
- if (__carry == 0) {
- while (__src <= __srcLastX) {
- /* copy over words */
- ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
- ((unsigned int *)(__src + __ptrDelta))[1] = ((unsigned int *)__src)[1];
- __src += 8;
- }
- while (__src <= __srcLast) {
- /* copy over bytes */
- __src[__ptrDelta] = __src[0];
- __src ++;
- }
- goto doneSource;
- }
- }
-
- __srcLastX = __srcLastX + 4;
- if (__src <= __srcLastX) {
- unsigned int __sum, __digit;
-
- __digit = ((unsigned *)__src)[0];
-
- asm ("addl %%eax,%%edx \n\
- movl $0,%%eax \n\
- adcl $0,%%eax"
- : "=a" ((unsigned long)(__carry)),
- "=d" ((unsigned long)(__sum))
- : "0" ((unsigned long)(__carry)),
- "1" (__digit) );
-
- ((unsigned int *)(__src + __ptrDelta))[0] = __sum;
- __src += 4;
-
- if (__carry == 0) {
- while (__src <= __srcLast) {
- /* copy over bytes */
- __src[__ptrDelta] = __src[0];
- __src ++;
- }
- goto doneSource;
- }
- }
- }
+ {
+ unsigned char *__srcLastX;
+
+ __srcLastX = __srcLast - 3 - 4;
+ while (__src <= __srcLastX) {
+ unsigned int __sum, __sum2;
+ unsigned __digit1, __digit2;
+
+ __digit1 = ((unsigned *)__src)[0];
+ __digit2 = ((unsigned *)__src)[1];
+ asm ("addl %%edx,%%ecx \n\
+ adcl $0, %%eax \n\
+ movl $0, %%edx \n\
+ adcl $0, %%edx"
+ : "=d" ((unsigned long)(__carry)),
+ "=c" ((unsigned long)(__sum)),
+ "=a" ((unsigned long)(__sum2))
+ : "0" ((unsigned long)(__carry)),
+ "1" (__digit1),
+ "2" (__digit2));
+
+ ((unsigned int *)(__src + __ptrDelta))[0] = __sum;
+ ((unsigned int *)(__src + __ptrDelta))[1] = __sum2;
+
+ __src += 8;
+
+ if (__carry == 0) {
+ while (__src <= __srcLastX) {
+ /* copy over words */
+ ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
+ ((unsigned int *)(__src + __ptrDelta))[1] = ((unsigned int *)__src)[1];
+ __src += 8;
+ }
+ while (__src <= __srcLast) {
+ /* copy over bytes */
+ __src[__ptrDelta] = __src[0];
+ __src ++;
+ }
+ goto doneSource;
+ }
+ }
+
+ __srcLastX = __srcLastX + 4;
+ if (__src <= __srcLastX) {
+ unsigned int __sum, __digit;
+
+ __digit = ((unsigned *)__src)[0];
+
+ asm ("addl %%eax,%%edx \n\
+ movl $0,%%eax \n\
+ adcl $0,%%eax"
+ : "=a" ((unsigned long)(__carry)),
+ "=d" ((unsigned long)(__sum))
+ : "0" ((unsigned long)(__carry)),
+ "1" (__digit) );
+
+ ((unsigned int *)(__src + __ptrDelta))[0] = __sum;
+ __src += 4;
+
+ if (__carry == 0) {
+ while (__src <= __srcLast) {
+ /* copy over bytes */
+ __src[__ptrDelta] = __src[0];
+ __src ++;
+ }
+ goto doneSource;
+ }
+ }
+ }
# endif
# else /* not i386-GNUC */
# if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
- {
- unsigned char *__srcLast4;
-
- /*
- * add long-wise
- */
- __srcLast4 = __srcLast - 3;
- while (__src <= __srcLast4) {
- unsigned int __sum;
-
- __sum = ((unsigned int *)__src)[0];
- asm {
- mov eax, __sum
- add eax, __carry
- mov edx, 0
- adc edx, 0
- mov __sum, eax
- mov __carry, edx
- }
-
- ((unsigned int *)(__src + __ptrDelta))[0] = __sum;
- __src += 4;
- if (__carry == 0) {
- while (__src <= __srcLast4) {
- /* copy over words */
- ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
- __src += 4;
- }
- while (__src <= __srcLast) {
- /* copy over bytes */
- __src[__ptrDelta] = __src[0];
- __src ++;
- }
- goto doneSource;
- }
- }
- }
+ {
+ unsigned char *__srcLast4;
+
+ /*
+ * add long-wise
+ */
+ __srcLast4 = __srcLast - 3;
+ while (__src <= __srcLast4) {
+ unsigned int __sum;
+
+ __sum = ((unsigned int *)__src)[0];
+ asm {
+ mov eax, __sum
+ add eax, __carry
+ mov edx, 0
+ adc edx, 0
+ mov __sum, eax
+ mov __carry, edx
+ }
+
+ ((unsigned int *)(__src + __ptrDelta))[0] = __sum;
+ __src += 4;
+ if (__carry == 0) {
+ while (__src <= __srcLast4) {
+ /* copy over words */
+ ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
+ __src += 4;
+ }
+ while (__src <= __srcLast) {
+ /* copy over bytes */
+ __src[__ptrDelta] = __src[0];
+ __src ++;
+ }
+ goto doneSource;
+ }
+ }
+ }
# else /* not i386-WIN32 */
# if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8)
- {
- unsigned char *__srcLast4;
-
- /*
- * add long-wise
- */
- __srcLast4 = __srcLast - 3;
- while (__src <= __srcLast4) {
- unsigned INT __sum;
-
- __sum = ((unsigned int *)__src)[0] + __carry;
- ((unsigned int *)(__src + __ptrDelta))[0] = __sum /* & 0xFFFF */;
- __src += 4;
- __carry = __sum >> 32;
- if (__carry == 0) {
- while (__src <= __srcLast4) {
- /* copy over words */
- ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
- __src += 4;
- }
- while (__src <= __srcLast) {
- /* copy over bytes */
- __src[__ptrDelta] = __src[0];
- __src ++;
- }
- goto doneSource;
- }
- }
- }
+ {
+ unsigned char *__srcLast4;
+
+ /*
+ * add long-wise
+ */
+ __srcLast4 = __srcLast - 3;
+ while (__src <= __srcLast4) {
+ unsigned INT __sum;
+
+ __sum = ((unsigned int *)__src)[0] + __carry;
+ ((unsigned int *)(__src + __ptrDelta))[0] = __sum /* & 0xFFFF */;
+ __src += 4;
+ __carry = __sum >> 32;
+ if (__carry == 0) {
+ while (__src <= __srcLast4) {
+ /* copy over words */
+ ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0];
+ __src += 4;
+ }
+ while (__src <= __srcLast) {
+ /* copy over bytes */
+ __src[__ptrDelta] = __src[0];
+ __src ++;
+ }
+ goto doneSource;
+ }
+ }
+ }
# endif /* LSB+64bit */
# endif /* __i386__ & WIN32 */
# endif /* __i386__ & GNUC */
- /*
- * add short-wise
- */
- while (__src < __srcLast) {
- __carry += ((unsigned short *)__src)[0];
- ((unsigned short *)(__src + __ptrDelta))[0] = __carry /* & 0xFFFF */;
- __carry >>= 16;
- __src += 2;
- }
- /*
- * last (odd) byte
- */
- if (__src <= __srcLast) {
- __carry += __src[0];
- __src[__ptrDelta] = __carry /* & 0xFF */;
- __carry >>= 8;
- __src++;
- }
+ /*
+ * add short-wise
+ */
+ while (__src < __srcLast) {
+ __carry += ((unsigned short *)__src)[0];
+ ((unsigned short *)(__src + __ptrDelta))[0] = __carry /* & 0xFFFF */;
+ __carry >>= 16;
+ __src += 2;
+ }
+ /*
+ * last (odd) byte
+ */
+ if (__src <= __srcLast) {
+ __carry += __src[0];
+ __src[__ptrDelta] = __carry /* & 0xFF */;
+ __carry >>= 8;
+ __src++;
+ }
#else /* not __LSBFIRST__ */
- /*
- * add byte-wise
- */
- while (__src <= __srcLast) {
- __carry += __src[0];
- __src[__ptrDelta] = __carry /* & 0xFF */;
- __src++;
- __carry >>= 8;
-
- if (__carry == 0) {
- while (__src <= __srcLast) {
- /* copy over rest */
- __src[__ptrDelta] = __src[0];
- __src++;
- }
- goto doneSource;
- }
- }
+ /*
+ * add byte-wise
+ */
+ while (__src <= __srcLast) {
+ __carry += __src[0];
+ __src[__ptrDelta] = __carry /* & 0xFF */;
+ __src++;
+ __carry >>= 8;
+
+ if (__carry == 0) {
+ while (__src <= __srcLast) {
+ /* copy over rest */
+ __src[__ptrDelta] = __src[0];
+ __src++;
+ }
+ goto doneSource;
+ }
+ }
#endif /* __LSBFIRST__ */
doneSource: ;
- /*
- * now, at most one other byte is to be stored ...
- */
- if (__len < __rsltLen) {
- __src[__ptrDelta] = __carry /* & 0xFF */;
- __src++;
- }
-
- if (__src[__ptrDelta-1]) { /* lastDigit */
- RETURN (result);
- }
- ok = true;
+ /*
+ * now, at most one other byte is to be stored ...
+ */
+ if (__len < __rsltLen) {
+ __src[__ptrDelta] = __carry /* & 0xFF */;
+ __src++;
+ }
+
+ if (__src[__ptrDelta-1]) { /* lastDigit */
+ RETURN (result);
+ }
+ ok = true;
}
%}.
ok ~~ true ifTrue:[
- index := 1.
- carry := aSmallInteger abs.
-
- [carry ~~ 0] whileTrue:[
- (index <= len) ifTrue:[
- carry := (digitByteArray basicAt:index) + carry.
- ].
- resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF).
- carry := carry bitShift:-8.
- index := index + 1
- ].
-
- (index <= rsltLen) ifTrue:[
- [index <= len] whileTrue:[
- resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index).
- index := index + 1
- ].
- lastDigit := 0.
- ].
-
- (lastDigit ~~ 0 and:[rsltLen > SmallInteger maxBytes]) 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 and:[rsltLen > SmallInteger maxBytes]) ifTrue:[
+ ^ result
+ ].
].
^ result compressed
@@ -3787,12 +3799,11 @@
len2 := otherDigitByteArray size.
len1 > len2 ifTrue:[
- lResult := len1
+ lResult := len1
] ifFalse:[
- lResult := (len1 max: len2) + 1.
+ lResult := (len1 max: len2) + 1.
].
- result := self class basicNew numberOfDigits:lResult.
- result sign:newSign.
+ result := self class basicNew numberOfDigits:lResult sign:newSign.
resultDigitByteArray := result digitBytes.
lastDigit := 0.
@@ -3803,202 +3814,202 @@
if (__isByteArray(_digitByteArray)
&& __isByteArray(otherDigitByteArray)
&& __isByteArray(resultDigitByteArray)) {
- int __len1 = __intVal(len1);
- int __len2 = __intVal(len2);
- int __minLen = __len1 < __len2 ? __len1 : __len2;
- int __index, __borrow = 0;
- INT __diff;
- unsigned char *__myDigits, *__otherDigits, *__resultDigits;
-
- ok = true;
-
- __resultDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
- __otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
- __myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
-
- __index = 1;
+ int __len1 = __intVal(len1);
+ int __len2 = __intVal(len2);
+ int __minLen = __len1 < __len2 ? __len1 : __len2;
+ int __index, __borrow = 0;
+ INT __diff;
+ unsigned char *__myDigits, *__otherDigits, *__resultDigits;
+
+ ok = true;
+
+ __resultDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+ __otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+ __myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+
+ __index = 1;
#if defined(__LSBFIRST__)
# if __POINTER_SIZE__ == 8
- /*
- * subtract int-wise
- */
- while ((__index+3) <= __minLen) {
- /* do not make this into one expression - ask cg why */
- __diff = ((unsigned int *)(__myDigits+__index-1))[0];
- __diff -= ((unsigned int *)(__otherDigits+__index-1))[0];
- __diff -= __borrow;
-
- if (__diff >= 0) {
- __borrow = 0;
- } else {
- __borrow = 1;
- /* __diff += 0x10000; */
- }
- ((unsigned int *)(__resultDigits+__index-1))[0] = __diff;
- __index += 4;
- }
+ /*
+ * subtract int-wise
+ */
+ while ((__index+3) <= __minLen) {
+ /* do not make this into one expression - ask cg why */
+ __diff = ((unsigned int *)(__myDigits+__index-1))[0];
+ __diff -= ((unsigned int *)(__otherDigits+__index-1))[0];
+ __diff -= __borrow;
+
+ if (__diff >= 0) {
+ __borrow = 0;
+ } else {
+ __borrow = 1;
+ /* __diff += 0x10000; */
+ }
+ ((unsigned int *)(__resultDigits+__index-1))[0] = __diff;
+ __index += 4;
+ }
# endif /* 64bit */
- /*
- * subtract short-wise
- */
- while (__index < __minLen) { /* i.e. index+1 <= minLen */
- /* do not make this into one expression - ask cg why */
- __diff = ((unsigned short *)(__myDigits+__index-1))[0];
- __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- } else {
- __borrow = 1;
- /* __diff += 0x10000; */
- }
- ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
- __index += 2;
- }
-
- if (__index == __minLen) {
- /* one of the operands has odd length - cannot continue short-wise */
- } else {
- if (__len1 > __len2) {
- while (__index < __len1) {
- /* do not make this into one expression - ask cg why */
- __diff = ((unsigned short *)(__myDigits+__index-1))[0];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
- __index += 2;
-
- /* copy over rest */
- while (__index < __len1) {
- ((unsigned short *)(__resultDigits+__index-1))[0] = ((unsigned short *)(__myDigits+__index-1))[0];
- __index+=2;
- }
- if (__index <= __len1) {
- __resultDigits[__index-1] = __myDigits[__index-1];
- __index++;
- }
- break;
- }
- __borrow = 1;
- /* __diff += 0x10000; */
- ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
- __index += 2;
- }
- } else {
- if (__len2 > __len1) {
- while (__index < __len2) {
- /* do not make this into one expression - ask cg why */
- __diff = 0;
- __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- } else {
- __borrow = 1;
- /* __diff += 0x10000; */
- }
- ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
- __index += 2;
- }
- }
- }
- }
+ /*
+ * subtract short-wise
+ */
+ while (__index < __minLen) { /* i.e. index+1 <= minLen */
+ /* do not make this into one expression - ask cg why */
+ __diff = ((unsigned short *)(__myDigits+__index-1))[0];
+ __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ } else {
+ __borrow = 1;
+ /* __diff += 0x10000; */
+ }
+ ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
+ __index += 2;
+ }
+
+ if (__index == __minLen) {
+ /* one of the operands has odd length - cannot continue short-wise */
+ } else {
+ if (__len1 > __len2) {
+ while (__index < __len1) {
+ /* do not make this into one expression - ask cg why */
+ __diff = ((unsigned short *)(__myDigits+__index-1))[0];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
+ __index += 2;
+
+ /* copy over rest */
+ while (__index < __len1) {
+ ((unsigned short *)(__resultDigits+__index-1))[0] = ((unsigned short *)(__myDigits+__index-1))[0];
+ __index+=2;
+ }
+ if (__index <= __len1) {
+ __resultDigits[__index-1] = __myDigits[__index-1];
+ __index++;
+ }
+ break;
+ }
+ __borrow = 1;
+ /* __diff += 0x10000; */
+ ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
+ __index += 2;
+ }
+ } else {
+ if (__len2 > __len1) {
+ while (__index < __len2) {
+ /* do not make this into one expression - ask cg why */
+ __diff = 0;
+ __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ } else {
+ __borrow = 1;
+ /* __diff += 0x10000; */
+ }
+ ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
+ __index += 2;
+ }
+ }
+ }
+ }
#endif
- /*
- * subtract byte-wise
- */
- while (__index <= __minLen) {
- /* do not make this into one expression - ask cg why */
- __diff = __myDigits[__index-1];
- __diff -= __otherDigits[__index-1];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- } else {
- __borrow = 1;
- /* __diff += 0x100; */
- }
- __resultDigits[__index-1] = __diff;
- __index++;
- }
-
- if (__len1 > __len2) {
- while (__index <= __len1) {
- /* do not make this into one expression - ask cg why */
- __diff = __myDigits[__index-1];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- /* copy over rest */
- __resultDigits[__index-1] = __diff;
- __index++;
- while (__index <= __len1) {
- __resultDigits[__index-1] = __myDigits[__index-1];
- __index++;
- }
- break;
- }
- __borrow = 1;
- /* __diff += 0x100; */
- __resultDigits[__index-1] = __diff;
- __index++;
- }
- } else {
- if (__len2 > __len1) {
- while (__index <= __len2) {
- /* do not make this into one expression - ask cg why */
- __diff = 0;
- __diff -= __otherDigits[__index-1];
- __diff -= __borrow;
- if (__diff >= 0) {
- __borrow = 0;
- } else {
- __borrow = 1;
- /* __diff += 0x100; */
- }
- __resultDigits[__index-1] = __diff;
- __index++;
- }
- }
- }
- borrow = __mkSmallInteger(__borrow);
- index = __mkSmallInteger(__index);
- lastDigit = __mkSmallInteger(__resultDigits[__intVal(lResult)-1]);
+ /*
+ * subtract byte-wise
+ */
+ while (__index <= __minLen) {
+ /* do not make this into one expression - ask cg why */
+ __diff = __myDigits[__index-1];
+ __diff -= __otherDigits[__index-1];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ } else {
+ __borrow = 1;
+ /* __diff += 0x100; */
+ }
+ __resultDigits[__index-1] = __diff;
+ __index++;
+ }
+
+ if (__len1 > __len2) {
+ while (__index <= __len1) {
+ /* do not make this into one expression - ask cg why */
+ __diff = __myDigits[__index-1];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ /* copy over rest */
+ __resultDigits[__index-1] = __diff;
+ __index++;
+ while (__index <= __len1) {
+ __resultDigits[__index-1] = __myDigits[__index-1];
+ __index++;
+ }
+ break;
+ }
+ __borrow = 1;
+ /* __diff += 0x100; */
+ __resultDigits[__index-1] = __diff;
+ __index++;
+ }
+ } else {
+ if (__len2 > __len1) {
+ while (__index <= __len2) {
+ /* do not make this into one expression - ask cg why */
+ __diff = 0;
+ __diff -= __otherDigits[__index-1];
+ __diff -= __borrow;
+ if (__diff >= 0) {
+ __borrow = 0;
+ } else {
+ __borrow = 1;
+ /* __diff += 0x100; */
+ }
+ __resultDigits[__index-1] = __diff;
+ __index++;
+ }
+ }
+ }
+ borrow = __mkSmallInteger(__borrow);
+ index = __mkSmallInteger(__index);
+ lastDigit = __mkSmallInteger(__resultDigits[__intVal(lResult)-1]);
}
%}.
ok == true ifFalse:[
- index := 1.
- borrow := 0.
-
- done := false.
- [done] whileFalse:[
- diff := borrow.
- (index <= len1) ifTrue:[
- diff := diff + (digitByteArray basicAt:index).
- (index <= len2) ifTrue:[
- diff := diff - (otherDigitByteArray basicAt:index)
- ]
- ] ifFalse:[
- (index <= len2) ifTrue:[
- diff := diff - (otherDigitByteArray basicAt:index)
- ] ifFalse:[
- "end reached"
- done := true
- ]
- ].
-
- "/ workaround for
- "/ gcc code generator bug
-
- (diff >= 0) ifTrue:[
- borrow := 0
- ] ifFalse:[
- borrow := -1.
- diff := diff + 16r100
- ].
+ index := 1.
+ borrow := 0.
+
+ done := false.
+ [done] whileFalse:[
+ diff := borrow.
+ (index <= len1) ifTrue:[
+ diff := diff + (digitByteArray basicAt:index).
+ (index <= len2) ifTrue:[
+ diff := diff - (otherDigitByteArray basicAt:index)
+ ]
+ ] ifFalse:[
+ (index <= len2) ifTrue:[
+ diff := diff - (otherDigitByteArray basicAt:index)
+ ] ifFalse:[
+ "end reached"
+ done := true
+ ]
+ ].
+
+ "/ workaround for
+ "/ gcc code generator bug
+
+ (diff >= 0) ifTrue:[
+ borrow := 0
+ ] ifFalse:[
+ borrow := -1.
+ diff := diff + 16r100
+ ].
"/ (diff < 0) ifTrue:[
"/ borrow := -1.
@@ -4007,40 +4018,40 @@
"/ borrow := 0
"/ ].
- resultDigitByteArray basicAt:index put:diff.
- index := index + 1
- ].
- lastDigit := resultDigitByteArray basicAt:lResult.
+ resultDigitByteArray basicAt:index put:diff.
+ index := index + 1
+ ].
+ lastDigit := resultDigitByteArray basicAt:lResult.
].
(borrow ~~ 0) ifTrue:[
- "/ must generate 255's complement
-
- result sign:newSign negated.
- [index <= lResult] whileTrue:[
- resultDigitByteArray basicAt:index put:16rFF.
- index := index + 1.
- ].
- index := lResult.
- [index > 0] whileTrue:[
- resultDigitByteArray basicAt:index put:(255 - (resultDigitByteArray at:index)).
- index := index - 1.
- ].
-
- index := 1.
- carry := 1.
- [carry ~~ 0] whileTrue:[
- (index <= lResult) ifTrue:[
- carry := (resultDigitByteArray basicAt:index) + carry.
- ].
- resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF).
- carry := carry bitShift:-8.
- index := index + 1
- ].
- lastDigit := resultDigitByteArray basicAt:lResult.
+ "/ must generate 255's complement
+
+ result sign:newSign negated.
+ [index <= lResult] whileTrue:[
+ resultDigitByteArray basicAt:index put:16rFF.
+ index := index + 1.
+ ].
+ index := lResult.
+ [index > 0] whileTrue:[
+ resultDigitByteArray basicAt:index put:(255 - (resultDigitByteArray at:index)).
+ index := index - 1.
+ ].
+
+ index := 1.
+ carry := 1.
+ [carry ~~ 0] whileTrue:[
+ (index <= lResult) ifTrue:[
+ carry := (resultDigitByteArray basicAt:index) + carry.
+ ].
+ resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF).
+ carry := carry bitShift:-8.
+ index := index + 1
+ ].
+ lastDigit := resultDigitByteArray basicAt:lResult.
].
(lastDigit == 0 or:[lResult <= SmallInteger maxBytes]) ifTrue:[
- ^ result compressed.
+ ^ result compressed.
].
^ result
@@ -4418,494 +4429,494 @@
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
- * (with sum==255, a carry could still occur from the next lower bytes)
- */
- _newLen = _len1;
- if ((_otherDigits[_len2 - 1] + _myDigits[_len1 - 1]) >= 0xFF) {
- _newLen++;
- } else {
- if (_newLen == sizeof(INT)) {
- OBJ _uint;
-
- /*
- * two word-sized numbers, no carry - a very common case ...
- */
+ 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
+ * (with sum==255, a carry could still occur from the next lower bytes)
+ */
+ _newLen = _len1;
+ if ((_otherDigits[_len2 - 1] + _myDigits[_len1 - 1]) >= 0xFF) {
+ _newLen++;
+ } else {
+ if (_newLen == sizeof(INT)) {
+ OBJ _uint;
+
+ /*
+ * two word-sized numbers, no carry - a very common case ...
+ */
#if defined(__LSB_FIRST__)
- unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits;
+ unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits;
#else
- unsigned INT _sum = __unsignedLongIntVal(self) + __unsignedLongIntVal(aLargeInteger);
+ unsigned INT _sum = __unsignedLongIntVal(self) + __unsignedLongIntVal(aLargeInteger);
#endif /* not LSB_FIRST */
- if (_sum <= _MAX_INT) {
- _uint = __mkSmallInteger(_sum * __intVal(newSign));
- } else {
- _uint = __MKULARGEINT(_sum);
- __LargeIntegerInstPtr(_uint)->l_sign = newSign;
- }
- RETURN (_uint);
- }
- }
- _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 (_sum <= _MAX_INT) {
+ _uint = __mkSmallInteger(_sum * __intVal(newSign));
+ } else {
+ _uint = __MKULARGEINT(_sum);
+ __LargeIntegerInstPtr(_uint)->l_sign = newSign;
+ }
+ RETURN (_uint);
+ }
+ }
+ _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(__LSBFIRST__)
# if (__POINTER_SIZE__ == 8) && defined(__GNUC__)
# if 0 /* not faster (on alpha) */
- {
- int _comLen7;
-
- /*
- * have a 64bit integers;
- * add quad-wise
- * accessing bytes at: [index-1][index][index+1]..[index+6]
- */
- _comLen7 = _comLen - 3 - 4;
- while (_index <= _comLen7) {
- UINT64 _sum, _t1, _t2;
-
- asm ("addq %5,%6,%1 /* sum */ \n\
- addq %0,%1,%1 /* plus carryIn */ \n\
- cmpult %1,%5,%2 /* was there a carry ? */ \n\
- cmpult %1,%6,%3 /* was there a carry ? */ \n\
- bis %2,%3,%0 /* carryOut */ \n\
- "
- : "=r" (_carry),
- "=r" (_sum),
- "r" (_t1),
- "r" (_t2)
- : "r" (_carry),
- "r" (((unsigned long *)(&(_myDigits[_index - 1])))[0]),
- "r" (((unsigned long *)(&(_otherDigits[_index - 1])))[0])
- );
- /* _sum = _sum & 0xFFFFFFFF; */
- ((unsigned long *)(&(_newDigits[_index - 1])))[0] = _sum;
- _index += 8;
- }
- }
+ {
+ int _comLen7;
+
+ /*
+ * have a 64bit integers;
+ * add quad-wise
+ * accessing bytes at: [index-1][index][index+1]..[index+6]
+ */
+ _comLen7 = _comLen - 3 - 4;
+ while (_index <= _comLen7) {
+ UINT64 _sum, _t1, _t2;
+
+ asm ("addq %5,%6,%1 /* sum */ \n\
+ addq %0,%1,%1 /* plus carryIn */ \n\
+ cmpult %1,%5,%2 /* was there a carry ? */ \n\
+ cmpult %1,%6,%3 /* was there a carry ? */ \n\
+ bis %2,%3,%0 /* carryOut */ \n\
+ "
+ : "=r" (_carry),
+ "=r" (_sum),
+ "r" (_t1),
+ "r" (_t2)
+ : "r" (_carry),
+ "r" (((unsigned long *)(&(_myDigits[_index - 1])))[0]),
+ "r" (((unsigned long *)(&(_otherDigits[_index - 1])))[0])
+ );
+ /* _sum = _sum & 0xFFFFFFFF; */
+ ((unsigned long *)(&(_newDigits[_index - 1])))[0] = _sum;
+ _index += 8;
+ }
+ }
# endif
# endif /* 64bit */
# if (__POINTER_SIZE__ == 8)
# if 0 /* not faster (on alpha) */
- {
- int _comLen7;
-
- /*
- * have a 64bit integers;
- * add quad-wise
- * accessing bytes at: [index-1][index][index+1]..[index+6]
- */
- _comLen7 = _comLen - 3 - 4;
- while (_index <= _comLen7) {
- UINT64 _sum, _t1, _t2;
-
- _t1 = ((UINT64 *)(&(_myDigits[_index - 1])))[0];
- _t2 = ((UINT64 *)(&(_otherDigits[_index - 1])))[0];
- _sum = _t1 + _t2 + _carry;
- ((UINT64 *)(&(_newDigits[_index - 1])))[0] = _sum;
- _carry = (_sum < _t1) | (_sum < _t2);
- _index += 8;
- }
- }
+ {
+ int _comLen7;
+
+ /*
+ * have a 64bit integers;
+ * add quad-wise
+ * accessing bytes at: [index-1][index][index+1]..[index+6]
+ */
+ _comLen7 = _comLen - 3 - 4;
+ while (_index <= _comLen7) {
+ UINT64 _sum, _t1, _t2;
+
+ _t1 = ((UINT64 *)(&(_myDigits[_index - 1])))[0];
+ _t2 = ((UINT64 *)(&(_otherDigits[_index - 1])))[0];
+ _sum = _t1 + _t2 + _carry;
+ ((UINT64 *)(&(_newDigits[_index - 1])))[0] = _sum;
+ _carry = (_sum < _t1) | (_sum < _t2);
+ _index += 8;
+ }
+ }
# endif
# endif /* 64bit */
# ifdef UINT64
- {
- int _comLen3;
-
- /*
- * have a 64bit integer type;
- * add int-wise
- * accessing bytes at: [index-1][index][index+1][index+2]
- */
- _comLen3 = _comLen - 3;
- while (_index <= _comLen3) {
- UINT64 _sum;
-
- /* do not merge the 3 lines below into one -
- * (will do sign extension then, which is wrong here)
- */
- _sum = (unsigned)_carry;
- _sum += ((unsigned int *)(&(_myDigits[_index - 1])))[0];
- _sum += ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
- _carry = _sum >> 32;
- /* _sum = _sum & 0xFFFFFFFF; */
- ((unsigned int *)(&(_newDigits[_index - 1])))[0] = _sum;
- _index += 4;
- }
- }
+ {
+ int _comLen3;
+
+ /*
+ * have a 64bit integer type;
+ * add int-wise
+ * accessing bytes at: [index-1][index][index+1][index+2]
+ */
+ _comLen3 = _comLen - 3;
+ while (_index <= _comLen3) {
+ UINT64 _sum;
+
+ /* do not merge the 3 lines below into one -
+ * (will do sign extension then, which is wrong here)
+ */
+ _sum = (unsigned)_carry;
+ _sum += ((unsigned int *)(&(_myDigits[_index - 1])))[0];
+ _sum += ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
+ _carry = _sum >> 32;
+ /* _sum = _sum & 0xFFFFFFFF; */
+ ((unsigned int *)(&(_newDigits[_index - 1])))[0] = _sum;
+ _index += 4;
+ }
+ }
# else
# if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4)
- {
- int _comLen3;
-
- _comLen3 = _comLen - 3 - 4;
- while (_index <= _comLen3) {
- unsigned int _sum, _sum2;
- unsigned int __in1A, __in1B, __in2A, __in2B;
-
- __in1A = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
- __in2A = ((unsigned int *)(&(_myDigits[_index - 1])))[1];
- __in1B = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
- __in2B = ((unsigned int *)(&(_otherDigits[_index - 1])))[1];
-
- asm ("addl %%edx,%%eax \n\
- movl $0,%%edx \n\
- adcl $0,%%edx \n\
- addl %5,%%eax \n\
- adcl $0,%%edx \n\
- \n\
- addl %%edx,%%ecx \n\
- movl $0,%%edx \n\
- adcl $0,%%edx \n\
- addl %7,%%ecx \n\
- adcl $0,%%edx \n\
- "
- : "=d" (_carry),
- "=a" (_sum),
- "=c" (_sum2)
- : "0" (_carry),
- "1" (__in1A),
- "rm" (__in1B),
- "2" (__in2A),
- "rm" (__in2B)
- );
-
- ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
- ((unsigned *)(&(_newDigits[_index - 1])))[1] = _sum2;
- _index += 8;
- }
- /*
- * add int-wise
- * accessing bytes at: [index-1][index][index+1][index+2]
- */
- _comLen3 = _comLen3 + 4;
- if (_index <= _comLen3) {
- unsigned int _sum;
- unsigned int __inA, __inB;
-
- __inA = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
- __inB = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
-
- asm ("addl %%edx,%%eax \n\
- movl $0,%%edx \n\
- adcl $0,%%edx \n\
- addl %4,%%eax \n\
- adcl $0,%%edx"
- : "=d" (_carry),
- "=a" (_sum)
- : "0" (_carry),
- "1" (__inA),
- "rm" (__inB)
- );
-
- ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
- _index += 4;
- }
- }
+ {
+ int _comLen3;
+
+ _comLen3 = _comLen - 3 - 4;
+ while (_index <= _comLen3) {
+ unsigned int _sum, _sum2;
+ unsigned int __in1A, __in1B, __in2A, __in2B;
+
+ __in1A = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
+ __in2A = ((unsigned int *)(&(_myDigits[_index - 1])))[1];
+ __in1B = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
+ __in2B = ((unsigned int *)(&(_otherDigits[_index - 1])))[1];
+
+ asm ("addl %%edx,%%eax \n\
+ movl $0,%%edx \n\
+ adcl $0,%%edx \n\
+ addl %5,%%eax \n\
+ adcl $0,%%edx \n\
+ \n\
+ addl %%edx,%%ecx \n\
+ movl $0,%%edx \n\
+ adcl $0,%%edx \n\
+ addl %7,%%ecx \n\
+ adcl $0,%%edx \n\
+ "
+ : "=d" (_carry),
+ "=a" (_sum),
+ "=c" (_sum2)
+ : "0" (_carry),
+ "1" (__in1A),
+ "rm" (__in1B),
+ "2" (__in2A),
+ "rm" (__in2B)
+ );
+
+ ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
+ ((unsigned *)(&(_newDigits[_index - 1])))[1] = _sum2;
+ _index += 8;
+ }
+ /*
+ * add int-wise
+ * accessing bytes at: [index-1][index][index+1][index+2]
+ */
+ _comLen3 = _comLen3 + 4;
+ if (_index <= _comLen3) {
+ unsigned int _sum;
+ unsigned int __inA, __inB;
+
+ __inA = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
+ __inB = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
+
+ asm ("addl %%edx,%%eax \n\
+ movl $0,%%edx \n\
+ adcl $0,%%edx \n\
+ addl %4,%%eax \n\
+ adcl $0,%%edx"
+ : "=d" (_carry),
+ "=a" (_sum)
+ : "0" (_carry),
+ "1" (__inA),
+ "rm" (__inB)
+ );
+
+ ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
+ _index += 4;
+ }
+ }
# endif /* __i386__ && GNUC */
# if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
- {
- int _comLen3;
-
- /*
- * add long-wise
- * accessing bytes at: [index-1][index][index+1][index+2]
- */
- _comLen3 = _comLen - 3;
- while (_index <= _comLen3) {
- unsigned int _sum, _v1, _v2;
-
- _v1 = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
- _v2 = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
- asm {
- mov eax, _v1
- add eax, _v2
- mov edx, 0
- adc edx, 0
- add eax, _carry
- adc edx, 0
- mov _carry, edx
- mov _sum, eax
- }
-
- ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
- _index += 4;
- }
- }
+ {
+ int _comLen3;
+
+ /*
+ * add long-wise
+ * accessing bytes at: [index-1][index][index+1][index+2]
+ */
+ _comLen3 = _comLen - 3;
+ while (_index <= _comLen3) {
+ unsigned int _sum, _v1, _v2;
+
+ _v1 = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
+ _v2 = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
+ asm {
+ mov eax, _v1
+ add eax, _v2
+ mov edx, 0
+ adc edx, 0
+ add eax, _carry
+ adc edx, 0
+ mov _carry, edx
+ mov _sum, eax
+ }
+
+ ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum;
+ _index += 4;
+ }
+ }
# endif /* __i386__ && WIN32 */
# endif /* INT64 */
- /*
- * add short-wise
- * accessing bytes at: [index-1][index]
- */
- while (_index < _comLen) {
- unsigned int _sum;
-
- _sum = _carry
- + ((unsigned short *)(&(_myDigits[_index - 1])))[0]
- + ((unsigned short *)(&(_otherDigits[_index - 1])))[0];
- _carry = _sum >> 16;
- /* _sum = _sum & 0xFFFF; */
- *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
- _index += 2;
- }
+ /*
+ * add short-wise
+ * accessing bytes at: [index-1][index]
+ */
+ while (_index < _comLen) {
+ unsigned int _sum;
+
+ _sum = _carry
+ + ((unsigned short *)(&(_myDigits[_index - 1])))[0]
+ + ((unsigned short *)(&(_otherDigits[_index - 1])))[0];
+ _carry = _sum >> 16;
+ /* _sum = _sum & 0xFFFF; */
+ *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
+ _index += 2;
+ }
#else
# ifdef __sparc__
- /*
- * add short-wise
- * accessing bytes at: [index-1][index]
- */
- while (_index < _comLen) {
- unsigned int _sum;
- unsigned short _v1, _v2;
-
- _v1 = ((unsigned short *)(&(_myDigits[_index - 1])))[0];
- _v2 = ((unsigned short *)(&(_otherDigits[_index - 1])))[0];
- _sum = _carry + (_v1>>8) + (_v2>>8);
- _carry = _sum >> 8;
- _newDigits[_index - 1] = _sum;
-
- _sum = _carry + (_v1 & 0xFF) + (_v2 & 0xFF);
- _carry = _sum >> 8;
- _newDigits[_index] = _sum;
- _index += 2;
- }
+ /*
+ * add short-wise
+ * accessing bytes at: [index-1][index]
+ */
+ while (_index < _comLen) {
+ unsigned int _sum;
+ unsigned short _v1, _v2;
+
+ _v1 = ((unsigned short *)(&(_myDigits[_index - 1])))[0];
+ _v2 = ((unsigned short *)(&(_otherDigits[_index - 1])))[0];
+ _sum = _carry + (_v1>>8) + (_v2>>8);
+ _carry = _sum >> 8;
+ _newDigits[_index - 1] = _sum;
+
+ _sum = _carry + (_v1 & 0xFF) + (_v2 & 0xFF);
+ _carry = _sum >> 8;
+ _newDigits[_index] = _sum;
+ _index += 2;
+ }
# endif
#endif /* __LSBFIRST__ */
- /*
- * add byte-wise
- */
- while (_index <= _comLen) {
- unsigned int _sum;
-
- _sum = _carry
- + _myDigits[_index - 1]
- + _otherDigits[_index - 1];
- _carry = _sum >> 8;
- /* _sum = _sum & 0xFF; */
- _newDigits[_index - 1] = _sum;
- _index++;
- }
-
- /*
- * rest
- */
- if (_len1 > _len2) {
+ /*
+ * add byte-wise
+ */
+ while (_index <= _comLen) {
+ unsigned int _sum;
+
+ _sum = _carry
+ + _myDigits[_index - 1]
+ + _otherDigits[_index - 1];
+ _carry = _sum >> 8;
+ /* _sum = _sum & 0xFF; */
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
+
+ /*
+ * rest
+ */
+ if (_len1 > _len2) {
#if defined(__LSBFIRST__)
- if (_index <= _len1) {
- if ((_index - 1) & 1) {
- /* odd byte */
- unsigned int _sum;
-
- _sum = _carry + _myDigits[_index - 1];
- _carry = _sum >> 8;
- /* _sum = _sum & 0xFF; */
- _newDigits[_index - 1] = _sum;
- _index++;
- }
-
- while (_index < _len1) {
- /* shorts */
- unsigned int _sum;
-
- _sum = _carry + *(unsigned short *)(&(_myDigits[_index - 1]));
- _carry = _sum >> 16;
- /* _sum = _sum & 0xFFFF; */
- *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
- _index += 2;
- }
-
- if (_index <= _len1) {
- /* last byte */
- unsigned int _sum;
-
- _sum = _carry + _myDigits[_index - 1];
- _carry = _sum >> 8;
- /* _sum = _sum & 0xFF; */
- _newDigits[_index - 1] = _sum;
- _index++;
- }
- }
+ if (_index <= _len1) {
+ if ((_index - 1) & 1) {
+ /* odd byte */
+ unsigned int _sum;
+
+ _sum = _carry + _myDigits[_index - 1];
+ _carry = _sum >> 8;
+ /* _sum = _sum & 0xFF; */
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
+
+ while (_index < _len1) {
+ /* shorts */
+ unsigned int _sum;
+
+ _sum = _carry + *(unsigned short *)(&(_myDigits[_index - 1]));
+ _carry = _sum >> 16;
+ /* _sum = _sum & 0xFFFF; */
+ *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
+ _index += 2;
+ }
+
+ if (_index <= _len1) {
+ /* last byte */
+ unsigned int _sum;
+
+ _sum = _carry + _myDigits[_index - 1];
+ _carry = _sum >> 8;
+ /* _sum = _sum & 0xFF; */
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
+ }
#else
- while (_index <= _len1) {
- unsigned int _sum;
-
- _sum = _carry + _myDigits[_index - 1];
- _carry = _sum >> 8;
- /* _sum = _sum & 0xFF; */
- _newDigits[_index - 1] = _sum;
- _index++;
- }
+ while (_index <= _len1) {
+ unsigned int _sum;
+
+ _sum = _carry + _myDigits[_index - 1];
+ _carry = _sum >> 8;
+ /* _sum = _sum & 0xFF; */
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
#endif /* not LSB */
- } else {
- if (_len2 > _len1) {
+ } else {
+ if (_len2 > _len1) {
#if defined(__LSBFIRST__)
- if (_index <= _len2) {
- if ((_index - 1) & 1) {
- /* odd byte */
- unsigned int _sum;
-
- _sum = _carry + _otherDigits[_index - 1];
- _carry = _sum >> 8;
- /* _sum = _sum & 0xFF; */
- _newDigits[_index - 1] = _sum;
- _index++;
- }
-
- while (_index < _len2) {
- /* shorts */
- unsigned int _sum;
-
- _sum = _carry + *(unsigned short *)(&(_otherDigits[_index - 1]));
- _carry = _sum >> 16;
- /* _sum = _sum & 0xFFFF; */
- *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
- _index += 2;
- }
-
- if (_index <= _len2) {
- /* last byte */
- unsigned int _sum;
-
- _sum = _carry + _otherDigits[_index - 1];
- _carry = _sum >> 8;
- /* _sum = _sum & 0xFF; */
- _newDigits[_index - 1] = _sum;
- _index++;
- }
- }
+ if (_index <= _len2) {
+ if ((_index - 1) & 1) {
+ /* odd byte */
+ unsigned int _sum;
+
+ _sum = _carry + _otherDigits[_index - 1];
+ _carry = _sum >> 8;
+ /* _sum = _sum & 0xFF; */
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
+
+ while (_index < _len2) {
+ /* shorts */
+ unsigned int _sum;
+
+ _sum = _carry + *(unsigned short *)(&(_otherDigits[_index - 1]));
+ _carry = _sum >> 16;
+ /* _sum = _sum & 0xFFFF; */
+ *(unsigned short *)(&(_newDigits[_index - 1])) = _sum;
+ _index += 2;
+ }
+
+ if (_index <= _len2) {
+ /* last byte */
+ unsigned int _sum;
+
+ _sum = _carry + _otherDigits[_index - 1];
+ _carry = _sum >> 8;
+ /* _sum = _sum & 0xFF; */
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
+ }
#else
- while (_index <= _len2) {
- unsigned int _sum;
-
- _sum = _carry + _otherDigits[_index - 1];
- _carry = _sum >> 8;
- /* _sum = _sum & 0xFF; */
- _newDigits[_index - 1] = _sum;
- _index++;
- }
+ while (_index <= _len2) {
+ unsigned int _sum;
+
+ _sum = _carry + _otherDigits[_index - 1];
+ _carry = _sum >> 8;
+ /* _sum = _sum & 0xFF; */
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
#endif /* not LSB */
- }
- }
-
- while (_index <= _newLen) {
- unsigned int _sum;
-
- _sum = _carry;
- _carry = _sum >> 8;
- /* _sum = _sum & 0xFF; */
- _newDigits[_index - 1] = _sum;
- _index++;
- }
+ }
+ }
+
+ while (_index <= _newLen) {
+ unsigned int _sum;
+
+ _sum = _carry;
+ _carry = _sum >> 8;
+ /* _sum = _sum & 0xFF; */
+ _newDigits[_index - 1] = _sum;
+ _index++;
+ }
}
%}.
resultDigitByteArray notNil ifTrue:[
- result := self class basicNew.
- result setDigits:resultDigitByteArray.
- result sign:newSign.
+ result := self class basicNew.
+ result setDigits:resultDigitByteArray.
+ result setSign:newSign.
] 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.
- result sign:newSign.
- resultDigitByteArray := result digitBytes.
-
- 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.
+ result sign:newSign.
+ resultDigitByteArray := result digitBytes.
+
+ 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
@@ -5369,13 +5380,33 @@
sign := 1.
!
+numberOfDigits:nDigits sign:newSign
+"/ digitByteArray := ByteArray uninitializedNew:nDigits.
+ digitByteArray := ByteArray new:nDigits.
+ sign := newSign.
+!
+
setDigits:digits
digitByteArray := digits.
sign := 1.
!
+setDigits:digits sign:newSign
+ digitByteArray := digits.
+ sign := newSign.
+!
+
+setSign:aNumber
+ "destructively change the sign of the receiver"
+
+ sign := aNumber
+!
+
sign:aNumber
- sign := aNumber
+ <resource: #obsolete>
+ "destructively change the sign of the receiver"
+
+ ^ self setSign:aNumber
! !
!LargeInteger methodsFor:'testing'!
@@ -5441,9 +5472,10 @@
!LargeInteger class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.225 2015-04-20 10:48:54 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.226 2015-05-20 16:01:28 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.225 2015-04-20 10:48:54 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.226 2015-05-20 16:01:28 cg Exp $'
! !
+