--- a/LargeInteger.st Fri Feb 26 06:41:16 2016 +0100
+++ b/LargeInteger.st Sat Feb 27 12:59:25 2016 +0000
@@ -1,6 +1,8 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1994 by Claus Gittinger
- All Rights Reserved
+ All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
@@ -25,7 +27,7 @@
copyright
"
COPYRIGHT (c) 1994 by Claus Gittinger
- All Rights Reserved
+ All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
@@ -64,12 +66,12 @@
change in the future.
[author:]
- Claus Gittinger
+ Claus Gittinger
[see also:]
- Number
- Float Fraction FixedPoint
- SmallInteger
+ Number
+ Float Fraction FixedPoint
+ SmallInteger
"
!
@@ -85,7 +87,7 @@
i printCR.
v := v * i.
(v / i) ~= last ifTrue:[
- self halt
+ self halt
].
last := v.
]
@@ -257,9 +259,9 @@
|digits|
msb == false ifTrue:[
- digits := aByteArrayOfDigits
+ digits := aByteArrayOfDigits
] ifFalse:[
- digits := aByteArrayOfDigits reversed
+ digits := aByteArrayOfDigits reversed
].
^ self basicNew setDigits:digits
@@ -302,9 +304,9 @@
"create and return a new LargeInteger with value taken from
the argument, aSmallInteger.
Notice:
- this should be only used internally, since such small
- largeIntegers do not normally occur in the system.
- (They are used by myself)
+ this should be only used internally, since such small
+ largeIntegers do not normally occur in the system.
+ (They are used by myself)
May change/be removed without notice."
^ self basicNew value:aSmallInteger
@@ -314,8 +316,6 @@
"Modified: / 8.5.1998 / 21:40:41 / cg"
! !
-
-
!LargeInteger class methodsFor:'queries'!
isBuiltInClass
@@ -341,14 +341,14 @@
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.
@@ -369,22 +369,22 @@
Use a special method for this case ...
"
((numberClass := aNumber class) == SmallInteger) ifTrue:[
- ^ self sumFromInteger:aNumber
+ ^ self sumFromInteger: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 > 0) ifTrue:[
- "I am positive"
- (otherSign > 0) ifTrue:[^ self absPlus:aNumber sign:1].
- (otherSign < 0) ifTrue:[^ self absMinus:aNumber sign:1].
- ^ self
+ "I am positive"
+ (otherSign > 0) ifTrue:[^ self absPlus:aNumber sign:1].
+ (otherSign < 0) ifTrue:[^ self absMinus:aNumber sign:1].
+ ^ self
].
"I am negative"
(otherSign > 0) ifTrue:[^ aNumber absMinus:self sign:1].
@@ -414,47 +414,47 @@
Use a special method for this case ...
"
((numberClass := aNumber class) == SmallInteger) ifTrue:[
- sign > 0 ifTrue:[
- aNumber > 0 ifTrue:[
- ^ self absFastMinus:aNumber sign:1
- ].
- ^ self absFastPlus:aNumber sign:1
- ].
- aNumber > 0 ifTrue:[
- ^ self absFastPlus:aNumber sign:-1
- ].
- ^ self absFastMinus:aNumber sign:-1
+ sign > 0 ifTrue:[
+ aNumber > 0 ifTrue:[
+ ^ self absFastMinus:aNumber sign:1
+ ].
+ ^ self absFastPlus:aNumber sign:1
+ ].
+ aNumber > 0 ifTrue:[
+ ^ self absFastPlus:aNumber sign:-1
+ ].
+ ^ self absFastMinus:aNumber sign:-1
].
"
if the argument is not a largeInteger, coerce
"
(numberClass == self class) ifFalse:[
- ^ self retry:#- coercing:aNumber
+ ^ self retry:#- coercing:aNumber
].
otherSign := aNumber sign.
(sign > 0) ifTrue:[
- "I am positive"
- (otherSign > 0) ifTrue:[
- "+large - +large"
- ^ self absMinus:aNumber sign:1
- ].
- (otherSign < 0) ifTrue:[
- "+large - -large"
- ^ self absPlus:aNumber sign:1
- ].
- "should not happen"
- ^ self
+ "I am positive"
+ (otherSign > 0) ifTrue:[
+ "+large - +large"
+ ^ self absMinus:aNumber sign:1
+ ].
+ (otherSign < 0) ifTrue:[
+ "+large - -large"
+ ^ self absPlus:aNumber sign:1
+ ].
+ "should not happen"
+ ^ self
].
"I am negative"
(otherSign > 0) ifTrue:[
- "-large - +large"
- ^ self absPlus:aNumber sign:-1
+ "-large - +large"
+ ^ self absPlus:aNumber sign:-1
].
(otherSign < 0) ifTrue:[
- "-large - -large"
- ^ self absMinus:aNumber sign:-1
+ "-large - -large"
+ ^ self absMinus:aNumber sign:-1
].
^ self
@@ -480,10 +480,10 @@
"return the quotient of the receiver and the argument, aNumber"
aNumber isInteger ifTrue:[
- ^ Fraction numerator:self denominator:aNumber
+ ^ Fraction numerator:self denominator:aNumber
].
aNumber isFraction ifTrue:[
- ^ Fraction numerator:(self * aNumber denominator) denominator:(aNumber numerator)
+ ^ Fraction numerator:(self * aNumber denominator) denominator:(aNumber numerator)
].
"this is a q&d hack - we loose lots of precision here ..."
@@ -498,57 +498,40 @@
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."
- |cls divMod quo abs "{ Class: SmallInteger }" n|
-
-
- cls := aNumber class.
+ |nrClass divMod quo|
+
+ nrClass := aNumber class.
"
this is the common case, dividing by a SmallInteger.
Use a special method for this case ...
"
- (cls == SmallInteger) ifTrue:[
- abs := aNumber.
- abs := abs abs.
- (abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r0fffffffffff 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
+ ((nrClass == SmallInteger) or:[ nrClass == self class]) ifFalse:[
+ ^ self retry:#// coercing:aNumber
].
-
- divMod isNil ifTrue:[
- divMod := self absDivMod:n.
- ].
+ divMod := self absDivMod:aNumber.
+
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 setSign:-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
@@ -575,8 +558,8 @@
0 // 40000000000000000
"
- "Modified: / 5.11.1996 / 16:39:36 / cg"
- "Modified: / 27.4.1999 / 19:50:26 / stefan"
+ "Modified: / 27-04-1999 / 19:50:26 / stefan"
+ "Modified: / 26-02-2016 / 22:28:27 / cg"
!
\\ aNumber
@@ -586,61 +569,39 @@
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:.
Redefined here for speed."
- |abs rem negativeDivisor|
-
- aNumber negative ifTrue:[
- negativeDivisor := true.
- abs := aNumber negated.
- ] ifFalse:[
- negativeDivisor := false.
- abs := aNumber.
+ |rem negativeDivisor nrClass|
+
+ nrClass := aNumber class.
+ ((nrClass == SmallInteger) or:[nrClass == self class]) ifFalse:[
+ ^ self retry:#\\ coercing:aNumber
].
- "
- this is the common case, dividing by a SmallInteger.
- 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
- ].
- ] ifFalse:[
- "
- 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 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 := (self absDivMod:aNumber) at:2.
+ rem ~~ 0 ifTrue:[
+ negativeDivisor := aNumber negative.
+ 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
@@ -685,51 +646,61 @@
divMod:aNumber
"return an array filled with
- (self // aNumber) and (self \\ aNumber).
+ (self // aNumber) and (self \\ aNumber).
The returned remainder has the same sign as aNumber.
The following is always true:
- (receiver // something) * something + (receiver \\ something) = receiver
+ (receiver // something) * something + (receiver \\ something) = 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.
This is redefined here for more performance
(as the remainder is generated as a side effect of division)"
- |cls n|
+ |nrClass|
((self < 0) or:[aNumber <= 0]) ifTrue:[
- ^ super divMod:aNumber
+ "/ this is rubbish
+ ^ super divMod:aNumber
].
"/ only handle the common case here
- cls := aNumber class.
- (cls == SmallInteger) ifTrue:[
- "
- this is the common case, dividing by a SmallInteger.
- Use a special method for this case ...
- "
- (aNumber between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffffff ifFalse:16r00ffffff)) ifTrue:[
- ^ self absFastDivMod:aNumber abs.
- ].
- n := aNumber asLargeInteger.
- ] ifFalse:[
- (cls == self class) ifFalse:[
- ^ super divMod:aNumber
- ].
- n := aNumber.
+ nrClass := aNumber class.
+ (nrClass == SmallInteger) ifFalse:[
+ (nrClass == self class) ifFalse:[
+ ^ super divMod:aNumber
+ ].
].
- ^ self absDivMod:n abs.
+ ^ self absDivMod:aNumber.
"
9000000000 // 4000000000 => 2
9000000000 \\ 4000000000 => 1000000000
+
9000000000 divMod: 4000000000 => #(2 1000000000)
+ -9000000000 divMod: 4000000000 => #(-3 3000000000)
+ 9000000000 divMod: -4000000000 => #(-3 -3000000000)
+ -9000000000 divMod: -4000000000 => #(2 -1000000000)
+
+ 9000000000000000000 absDivMod: 400000000000000 => #(22500 0)
+ -9000000000000000000 absDivMod: 400000000000000 => #(22500 0)
+ 9000000000000000000 absDivMod: -400000000000000 => #(22500 0)
+ -9000000000000000000 absDivMod: -400000000000000 => #(22500 0)
+
+ 9000000000000000000 absDivMod: 4000000000000000 => #(2250 0)
+ -9000000000000000000 absDivMod: 4000000000000000 => #(2250 0)
+ 9000000000000000000 absDivMod: -4000000000000000 => #(2250 0)
+ -9000000000000000000 absDivMod: -4000000000000000 => #(2250 0)
+
+ 9000000000000000000 absDivMod: 4000000000000000000 => #(2 1000000000000000000)
+ -9000000000000000000 absDivMod: 4000000000000000000 => #(2 1000000000000000000)
+ 9000000000000000000 absDivMod: -4000000000000000000 => #(2 1000000000000000000)
+ -9000000000000000000 absDivMod: -4000000000000000000 => #(2 1000000000000000000)
"
"Created: / 29.10.1996 / 21:22:05 / cg"
@@ -747,73 +718,73 @@
special case for SmallInteger minVal
"
sign == 1 ifTrue:[
- sz := digitByteArray size.
+ sz := digitByteArray size.
%{
#ifdef __SCHTEAM__
#else /* not SCHTEAM */
- 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));
+ }
+ }
#endif
%}.
- sz == SmallInteger maxBytes ifTrue:[
- (digitByteArray at:1) == 0 ifTrue:[
- (digitByteArray at:2) == 0 ifTrue:[
- (digitByteArray at:3) == 0 ifTrue:[
- SmallInteger maxBytes == 8 ifTrue:[
- (digitByteArray at:4) == 0 ifTrue:[
- (digitByteArray at:5) == 0 ifTrue:[
- (digitByteArray at:6) == 0 ifTrue:[
- (digitByteArray at:7) == 0 ifTrue:[
- (digitByteArray at:8) == 16r40 ifTrue:[
- ^ SmallInteger minVal
- ].
- ]
- ]
- ]
- ]
- ] ifFalse:[
- (digitByteArray at:4) == 16r40 ifTrue:[
- ^ SmallInteger minVal
- ].
- ]
- ]
- ]
- ]
- ].
+ sz == SmallInteger maxBytes ifTrue:[
+ (digitByteArray at:1) == 0 ifTrue:[
+ (digitByteArray at:2) == 0 ifTrue:[
+ (digitByteArray at:3) == 0 ifTrue:[
+ SmallInteger maxBytes == 8 ifTrue:[
+ (digitByteArray at:4) == 0 ifTrue:[
+ (digitByteArray at:5) == 0 ifTrue:[
+ (digitByteArray at:6) == 0 ifTrue:[
+ (digitByteArray at:7) == 0 ifTrue:[
+ (digitByteArray at:8) == 16r40 ifTrue:[
+ ^ SmallInteger minVal
+ ].
+ ]
+ ]
+ ]
+ ]
+ ] ifFalse:[
+ (digitByteArray at:4) == 16r40 ifTrue:[
+ ^ SmallInteger minVal
+ ].
+ ]
+ ]
+ ]
+ ]
+ ].
].
"/ cg - can share the digits ...
newNumber := self class digitBytes:digitByteArray sign:(sign negated).
@@ -824,43 +795,23 @@
"return the quotient of the receiver and the argument, aNumber.
The result is truncated toward zero (which is different from //, which
truncates toward negative infinity).
- The results sign is negative if the receiver has a sign
- different from the args sign.
+ The result's sign is negative if the receiver has a sign different from the arg's sign.
The following is always true:
- (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
- "
-
- |otherSign quo abs "{ Class: SmallInteger }" |
-
- otherSign := aNumber sign.
-
- "
- this is the common case, dividing by a SmallInteger.
- Use a special method for this case ...
+ (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
"
- (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 setSign:-1
- ]
+
+ |nrClass quo |
+
+ nrClass := aNumber class.
+ ((nrClass == SmallInteger) or:[ nrClass == self class] ) ifFalse:[
+ ^ self retry:#quo: coercing:aNumber
].
- "
- if the argument is not a largeInteger, coerce
- "
- (aNumber class == self class) ifFalse:[
- ^ self retry:#quo: coercing:aNumber
+ quo := (self absDivMod:aNumber) at:1.
+ (sign == aNumber sign) ifTrue:[
+ ^ quo
].
-
- sign < 0 ifTrue:[
- (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber negated) at:1].
- ] ifFalse:[
- (sign == otherSign) ifTrue:[^ (self absDivMod:aNumber) at:1].
- ].
- ^ ((self absDivMod:aNumber) at:1) setSign:-1
+ ^ quo setSign:-1
"
900 // 400
@@ -892,36 +843,20 @@
"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
- "
-
- |rem abs "{ Class: SmallInteger }" |
-
- "
- this is the common case, dividing by a SmallInteger.
- Use special code for this case ...
+ (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
"
- (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
- ].
- ] ifFalse:[
- "
- if the argument is not a largeInteger, coerce
- "
- (aNumber class == self class) ifFalse:[
- ^ self retry:#rem coercing:aNumber
- ].
-
- rem := self absMod:aNumber
+
+ |nrClass rem|
+
+ nrClass := aNumber class.
+ ((nrClass == SmallInteger) or:[ nrClass == self class ]) ifFalse:[
+ ^ self retry:#rem coercing:aNumber
].
-
- sign < 0 ifTrue:[
- ^ rem setSign:-1
+ rem := (self absDivMod:aNumber) at:2.
+ rem ~~ 0 ifTrue:[
+ sign < 0 ifTrue:[
+ ^ rem setSign:-1
+ ].
].
^ rem
@@ -958,139 +893,139 @@
%{ /* NOCONTEXT */
if (__isSmallInteger(anInteger)) {
- INT v2 = __intVal(anInteger);
- INT v1;
+ INT v2 = __intVal(anInteger);
+ INT v1;
#if defined(__LSBFIRST__)
- v1 = *(INT *)(__byteArrayVal(__INST(digitByteArray)));
+ v1 = *(INT *)(__byteArrayVal(__INST(digitByteArray)));
#else
- unsigned char *digits = (unsigned char *)(__byteArrayVal(__INST(digitByteArray)));
-
- v1 = digits[0] & 0xFF;
- v1 = v1 | ((digits[1] & 0xFF)<<8);
- v1 = v1 | ((digits[2] & 0xFF)<<16);
- v1 = v1 | ((digits[3] & 0xFF)<<24);
+ unsigned char *digits = (unsigned char *)(__byteArrayVal(__INST(digitByteArray)));
+
+ v1 = digits[0] & 0xFF;
+ v1 = v1 | ((digits[1] & 0xFF)<<8);
+ v1 = v1 | ((digits[2] & 0xFF)<<16);
+ v1 = v1 | ((digits[3] & 0xFF)<<24);
# if (__POINTER_SIZE__ == 8)
- v1 = v1 | ((digits[4] & 0xFF)<<32);
- v1 = v1 | ((digits[5] & 0xFF)<<40);
- v1 = v1 | ((digits[6] & 0xFF)<<48);
- v1 = v1 | ((digits[7] & 0xFF)<<56);
+ v1 = v1 | ((digits[4] & 0xFF)<<32);
+ v1 = v1 | ((digits[5] & 0xFF)<<40);
+ v1 = v1 | ((digits[6] & 0xFF)<<48);
+ v1 = v1 | ((digits[7] & 0xFF)<<56);
#endif
#endif
- RETURN ( __mkSmallInteger(v1 & v2) );
+ RETURN ( __mkSmallInteger(v1 & v2) );
}
if (__isLargeInteger(anInteger)) {
- OBJ _myDigitByteArray = __INST(digitByteArray);
- OBJ _otherDigitByteArray = __LargeIntegerInstPtr(anInteger)->l_digits;
-
- if (__isByteArray(_myDigitByteArray)
- && __isByteArray(_otherDigitByteArray)) {
- unsigned char *pDigits1, *pDigits2;
- int size1, size2, minSize;
- union {
- double d; // force align
- unsigned char chars[2048+8];
- } buffer;
- unsigned char *pRslt;
- OBJ newDigits, newLarge;
-
- pDigits1 = (unsigned char *)(__byteArrayVal(_myDigitByteArray));
- pDigits2 = (unsigned char *)(__byteArrayVal(_otherDigitByteArray));
- pRslt = (void *)(buffer.chars);
-
- size1 = __byteArraySize(_myDigitByteArray);
- size2 = __byteArraySize(_otherDigitByteArray);
- minSize = (size1 < size2) ? size1 : size2;
- if (minSize <= sizeof(buffer.chars)) {
- int n = minSize;
-
- /* not worth it - but a nice try and first testbed for mmx... */
+ OBJ _myDigitByteArray = __INST(digitByteArray);
+ OBJ _otherDigitByteArray = __LargeIntegerInstPtr(anInteger)->l_digits;
+
+ if (__isByteArray(_myDigitByteArray)
+ && __isByteArray(_otherDigitByteArray)) {
+ unsigned char *pDigits1, *pDigits2;
+ int size1, size2, minSize;
+ union {
+ double d; // force align
+ unsigned char chars[2048+8];
+ } buffer;
+ unsigned char *pRslt;
+ OBJ newDigits, newLarge;
+
+ pDigits1 = (unsigned char *)(__byteArrayVal(_myDigitByteArray));
+ pDigits2 = (unsigned char *)(__byteArrayVal(_otherDigitByteArray));
+ pRslt = (void *)(buffer.chars);
+
+ size1 = __byteArraySize(_myDigitByteArray);
+ size2 = __byteArraySize(_otherDigitByteArray);
+ minSize = (size1 < size2) ? size1 : size2;
+ if (minSize <= sizeof(buffer.chars)) {
+ int n = minSize;
+
+ /* not worth it - but a nice try and first testbed for mmx... */
#define x__USE_MMX__
#ifdef __USE_MMX__
#ifdef __VISUALC__
- if (((INT)pRslt & 7) == 0) { // 8-byte aligned
- if (((INT)pDigits1 & 7) == ((INT)pDigits2 & 7)) { // same align
- while (((INT)pDigits1 & 7) && (n >= sizeof(int))) {
- ((int *)pRslt)[0] = ((int *)pDigits1)[0] & ((int *)pDigits2)[0];
- pRslt += sizeof(int);
- pDigits1 += sizeof(int);
- pDigits2 += sizeof(int);
- pDigits2 += sizeof(int);
- n -= sizeof(int);
- }
- for (; n >= 8; n -= 8) {
- __asm {
- mov eax, pDigits1
- movq mm0, [eax]
- mov eax, pDigits2
- movq mm1, [eax]
- pand mm0, mm1
- mov eax, pRslt
- movq [eax], mm0
- }
- pDigits1 += 8;
- pDigits2 += 8;
- pRslt += 8;
- }
- __asm {
- emms ; switch back to FPU state.
- }
- }
- }
+ if (((INT)pRslt & 7) == 0) { // 8-byte aligned
+ if (((INT)pDigits1 & 7) == ((INT)pDigits2 & 7)) { // same align
+ while (((INT)pDigits1 & 7) && (n >= sizeof(int))) {
+ ((int *)pRslt)[0] = ((int *)pDigits1)[0] & ((int *)pDigits2)[0];
+ pRslt += sizeof(int);
+ pDigits1 += sizeof(int);
+ pDigits2 += sizeof(int);
+ pDigits2 += sizeof(int);
+ n -= sizeof(int);
+ }
+ for (; n >= 8; n -= 8) {
+ __asm {
+ mov eax, pDigits1
+ movq mm0, [eax]
+ mov eax, pDigits2
+ movq mm1, [eax]
+ pand mm0, mm1
+ mov eax, pRslt
+ movq [eax], mm0
+ }
+ pDigits1 += 8;
+ pDigits2 += 8;
+ pRslt += 8;
+ }
+ __asm {
+ emms ; switch back to FPU state.
+ }
+ }
+ }
#endif /* __VISUALC__ */
#endif /* __USE_MMX__ */
- for (; n >= sizeof(INT)*4; n -= sizeof(INT)*4) {
- ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0];
- ((INT *)pRslt)[1] = ((INT *)pDigits1)[1] & ((INT *)pDigits2)[1];
- ((INT *)pRslt)[2] = ((INT *)pDigits1)[2] & ((INT *)pDigits2)[2];
- ((INT *)pRslt)[3] = ((INT *)pDigits1)[3] & ((INT *)pDigits2)[3];
- pRslt += sizeof(INT)*4;
- pDigits1 += sizeof(INT)*4;
- pDigits2 += sizeof(INT)*4;
- }
- for (; n >= sizeof(INT); n -= sizeof(INT)) {
- ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0];
- pRslt += sizeof(INT);
- pDigits1 += sizeof(INT);
- pDigits2 += sizeof(INT);
- }
- for (; n > 0; n--) {
- *pRslt = *pDigits1 & *pDigits2;
- pRslt++;
- pDigits1++;
- pDigits2++;
- }
- // normalize
- while ((pRslt[-1]==0) && (pRslt > buffer.chars)) {
- pRslt--;
- }
-
- // allocate result
- n = pRslt-buffer.chars;
- if (n <= sizeof(INT)) {
- INT val = 0;
-
- // make it a smallInteger / 32bitInteger
- while (n > 0) {
- val = (val << 8) + buffer.chars[--n];
- }
- RETURN (__MKUINT(val));
- }
- newDigits = __MKBYTEARRAY(buffer.chars, n);
- if (newDigits) {
- __PROTECT__(newDigits);
- newLarge = __STX___new(sizeof(struct __LargeInteger));
- __UNPROTECT__(newDigits);
- if (newLarge) {
- __InstPtr(newLarge)->o_class = LargeInteger; __STORE(newLarge, LargeInteger);
- __LargeIntegerInstPtr(newLarge)->l_digits = newDigits; __STORE(newLarge, newDigits);
- __LargeIntegerInstPtr(newLarge)->l_sign = __MKSMALLINT(1);
- RETURN (newLarge);
- }
- }
- }
- }
+ for (; n >= sizeof(INT)*4; n -= sizeof(INT)*4) {
+ ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0];
+ ((INT *)pRslt)[1] = ((INT *)pDigits1)[1] & ((INT *)pDigits2)[1];
+ ((INT *)pRslt)[2] = ((INT *)pDigits1)[2] & ((INT *)pDigits2)[2];
+ ((INT *)pRslt)[3] = ((INT *)pDigits1)[3] & ((INT *)pDigits2)[3];
+ pRslt += sizeof(INT)*4;
+ pDigits1 += sizeof(INT)*4;
+ pDigits2 += sizeof(INT)*4;
+ }
+ for (; n >= sizeof(INT); n -= sizeof(INT)) {
+ ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0];
+ pRslt += sizeof(INT);
+ pDigits1 += sizeof(INT);
+ pDigits2 += sizeof(INT);
+ }
+ for (; n > 0; n--) {
+ *pRslt = *pDigits1 & *pDigits2;
+ pRslt++;
+ pDigits1++;
+ pDigits2++;
+ }
+ // normalize
+ while ((pRslt[-1]==0) && (pRslt > buffer.chars)) {
+ pRslt--;
+ }
+
+ // allocate result
+ n = pRslt-buffer.chars;
+ if (n <= sizeof(INT)) {
+ INT val = 0;
+
+ // make it a smallInteger / 32bitInteger
+ while (n > 0) {
+ val = (val << 8) + buffer.chars[--n];
+ }
+ RETURN (__MKUINT(val));
+ }
+ newDigits = __MKBYTEARRAY(buffer.chars, n);
+ if (newDigits) {
+ __PROTECT__(newDigits);
+ newLarge = __STX___new(sizeof(struct __LargeInteger));
+ __UNPROTECT__(newDigits);
+ if (newLarge) {
+ __InstPtr(newLarge)->o_class = LargeInteger; __STORE(newLarge, LargeInteger);
+ __LargeIntegerInstPtr(newLarge)->l_digits = newDigits; __STORE(newLarge, newDigits);
+ __LargeIntegerInstPtr(newLarge)->l_sign = __MKSMALLINT(1);
+ RETURN (newLarge);
+ }
+ }
+ }
+ }
}
%}.
^ super bitAnd:anInteger
@@ -1119,11 +1054,11 @@
anInteger class ~~ LargeInteger ifTrue:[^ super bitXor:anInteger].
(len1 := anInteger digitLength) > (len2 := self digitLength) ifTrue:[
- newBytes := anInteger digitBytes copy.
- newBytes bitXorBytesFrom:1 to:len2 with:digitByteArray startingAt:1
+ newBytes := anInteger digitBytes copy.
+ newBytes bitXorBytesFrom:1 to:len2 with:digitByteArray startingAt:1
] ifFalse:[
- newBytes := digitByteArray copy.
- newBytes bitXorBytesFrom:1 to:len1 with:anInteger digits startingAt:1
+ newBytes := digitByteArray copy.
+ newBytes bitXorBytesFrom:1 to:len1 with:anInteger digits startingAt:1
].
^ (self class digitBytes:newBytes) compressed
@@ -1138,9 +1073,9 @@
bigNum1 := 2 raisedToInteger:512.
bigNum2 := 2 raisedToInteger:510.
Time millisecondsToRun:[
- 1000000 timesRepeat:[
- bigNum1 bitXor:bigNum2.
- ]
+ 1000000 timesRepeat:[
+ bigNum1 bitXor:bigNum2.
+ ]
]
"
!
@@ -1166,85 +1101,85 @@
* quickly advance over full 0-words
*/
if (__isByteArray(__digitByteArray)) {
- int __sz = __byteArraySize(__digitByteArray);
- unsigned char *__bP = __byteArrayVal(__digitByteArray);
- unsigned char *__bP0 = __bP;
-
- sz = __MKSMALLINT(__sz);
+ int __sz = __byteArraySize(__digitByteArray);
+ unsigned char *__bP = __byteArrayVal(__digitByteArray);
+ unsigned char *__bP0 = __bP;
+
+ sz = __MKSMALLINT(__sz);
#ifdef __UNROLL_LOOPS__
- while (__sz > (sizeof(INT) * 4)) {
- if (( ((INT *)__bP)[0]
- | ((INT *)__bP)[1]
- | ((INT *)__bP)[2]
- | ((INT *)__bP)[3] ) != 0) break;
- __sz -= sizeof(INT) * 4;
- __bP += sizeof(INT) * 4;
- }
+ while (__sz > (sizeof(INT) * 4)) {
+ if (( ((INT *)__bP)[0]
+ | ((INT *)__bP)[1]
+ | ((INT *)__bP)[2]
+ | ((INT *)__bP)[3] ) != 0) break;
+ __sz -= sizeof(INT) * 4;
+ __bP += sizeof(INT) * 4;
+ }
#endif
- while (__sz > sizeof(INT)) {
- if ( ((INT *)__bP)[0] != 0 ) break;
- __sz -= sizeof(INT);
- __bP += sizeof(INT);
- }
- while (__sz > 0) {
- unsigned int c;
-
- if ( (c = *__bP) != 0 ) {
- int bitIdx = (__bP - __bP0) * 8;
+ while (__sz > sizeof(INT)) {
+ if ( ((INT *)__bP)[0] != 0 ) break;
+ __sz -= sizeof(INT);
+ __bP += sizeof(INT);
+ }
+ while (__sz > 0) {
+ unsigned int c;
+
+ if ( (c = *__bP) != 0 ) {
+ int bitIdx = (__bP - __bP0) * 8;
#ifdef __BSF
- {
- int index;
- int t = c;
-
- index = __BSF(t);
- RETURN ( __mkSmallInteger(index + 1 + bitIdx) );
- }
+ {
+ int index;
+ int t = c;
+
+ index = __BSF(t);
+ RETURN ( __mkSmallInteger(index + 1 + bitIdx) );
+ }
#else
- if (c & 0x0F) {
- if (c & 0x03) {
- if (c & 0x01) {
- RETURN ( __mkSmallInteger( bitIdx + 1) );
- } else {
- RETURN ( __mkSmallInteger( bitIdx + 2) );
- }
- } else {
- if (c & 0x04) {
- RETURN ( __mkSmallInteger( bitIdx + 3) );
- } else {
- RETURN ( __mkSmallInteger( bitIdx + 4) );
- }
- }
- } else {
- if (c & 0x30) {
- if (c & 0x10) {
- RETURN ( __mkSmallInteger( bitIdx + 5) );
- } else {
- RETURN ( __mkSmallInteger( bitIdx + 6) );
- }
- } else {
- if (c & 0x40) {
- RETURN ( __mkSmallInteger( bitIdx + 7) );
- } else {
- RETURN ( __mkSmallInteger( bitIdx + 8) );
- }
- }
- }
+ if (c & 0x0F) {
+ if (c & 0x03) {
+ if (c & 0x01) {
+ RETURN ( __mkSmallInteger( bitIdx + 1) );
+ } else {
+ RETURN ( __mkSmallInteger( bitIdx + 2) );
+ }
+ } else {
+ if (c & 0x04) {
+ RETURN ( __mkSmallInteger( bitIdx + 3) );
+ } else {
+ RETURN ( __mkSmallInteger( bitIdx + 4) );
+ }
+ }
+ } else {
+ if (c & 0x30) {
+ if (c & 0x10) {
+ RETURN ( __mkSmallInteger( bitIdx + 5) );
+ } else {
+ RETURN ( __mkSmallInteger( bitIdx + 6) );
+ }
+ } else {
+ if (c & 0x40) {
+ RETURN ( __mkSmallInteger( bitIdx + 7) );
+ } else {
+ RETURN ( __mkSmallInteger( bitIdx + 8) );
+ }
+ }
+ }
#endif
- break;
- }
- __sz--;
- __bP++;
- }
- idx0 = __mkSmallInteger( __bP - __bP0 + 1 );
+ break;
+ }
+ __sz--;
+ __bP++;
+ }
+ idx0 = __mkSmallInteger( __bP - __bP0 + 1 );
}
%}.
"/ never actually reached
idx0 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)
+ ]
].
^ 0 "/ should not happen
@@ -1268,24 +1203,24 @@
((1 bitShift:64)-1) highBit
1 to:1000 do:[:idx |
- self assert:(( 1 bitShift:idx) lowBit = (idx+1)).
- self assert:(( 1 bitShift:idx) lowBit = ( 1 bitShift:idx) highBit).
- self assert:(( 3 bitShift:idx) lowBit = (idx+1)).
- self assert:(( 7 bitShift:idx) lowBit = (idx+1)).
- self assert:(( 15 bitShift:idx) lowBit = (idx+1)).
- self assert:(( 31 bitShift:idx) lowBit = (idx+1)).
- self assert:(( 63 bitShift:idx) lowBit = (idx+1)).
- self assert:(( 127 bitShift:idx) lowBit = (idx+1)).
- self assert:(( 255 bitShift:idx) lowBit = (idx+1)).
+ self assert:(( 1 bitShift:idx) lowBit = (idx+1)).
+ self assert:(( 1 bitShift:idx) lowBit = ( 1 bitShift:idx) highBit).
+ self assert:(( 3 bitShift:idx) lowBit = (idx+1)).
+ self assert:(( 7 bitShift:idx) lowBit = (idx+1)).
+ self assert:(( 15 bitShift:idx) lowBit = (idx+1)).
+ self assert:(( 31 bitShift:idx) lowBit = (idx+1)).
+ self assert:(( 63 bitShift:idx) lowBit = (idx+1)).
+ self assert:(( 127 bitShift:idx) lowBit = (idx+1)).
+ self assert:(( 255 bitShift:idx) lowBit = (idx+1)).
]
|num|
num := (1 bitShift:1000).
Time millisecondsToRun:[
- 1000000 timesRepeat:[
- num lowBit
- ]
+ 1000000 timesRepeat:[
+ num lowBit
+ ]
]
"
@@ -1297,29 +1232,29 @@
bitAt:anIntegerIndex
"return the value of the index's bit (index starts at 1) as 0 or 1.
Notice: the result of bitAt: on negative receivers is not
- defined in the language standard (since the implementation
- is free to choose any internal representation for integers)"
+ defined in the language standard (since the implementation
+ is free to choose any internal representation for integers)"
%{ /* NOCONTEXT */
if (__isSmallInteger(anIntegerIndex)) {
- INT idx = __smallIntegerVal(anIntegerIndex) - 1;
-
- if (idx >= 0) {
- int v1;
- int byteOffset = idx / 8;
- int digitLen = __byteArraySize(__INST(digitByteArray));
-
- if (digitLen < byteOffset) {
- RETURN(__mkSmallInteger(0));
- }
-
- v1 = (__byteArrayVal(__INST(digitByteArray)))[byteOffset];
- if (v1 & (1 << (idx % 8))) {
- RETURN(__mkSmallInteger(1));
- } else {
- RETURN(__mkSmallInteger(0));
- }
- }
+ INT idx = __smallIntegerVal(anIntegerIndex) - 1;
+
+ if (idx >= 0) {
+ int v1;
+ int byteOffset = idx / 8;
+ int digitLen = __byteArraySize(__INST(digitByteArray));
+
+ if (digitLen < byteOffset) {
+ RETURN(__mkSmallInteger(0));
+ }
+
+ v1 = (__byteArrayVal(__INST(digitByteArray)))[byteOffset];
+ if (v1 & (1 << (idx % 8))) {
+ RETURN(__mkSmallInteger(1));
+ } else {
+ RETURN(__mkSmallInteger(0));
+ }
+ }
}
%}.
^ super bitAt:anIntegerIndex
@@ -1347,23 +1282,23 @@
|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)).
+ at:byteIndexOfBitToSet
+ put:((newDigitBytes at:byteIndexOfBitToSet) setBit:(((index-1)\\8)+1)).
^ self class digitBytes:newDigitBytes sign:sign
"
@@ -1410,19 +1345,19 @@
int count;
if (__isSmallInteger(shiftCount)) {
- count = __intVal(shiftCount);
- count = count % 32;
-
- bits = __unsignedLongIntVal(self);
- if (count > 0) {
- bits = (bits << count) | (bits >> (32-count));
- } else {
- bits = (bits >> (-count)) | (bits << (32-(-count)));
- }
+ count = __intVal(shiftCount);
+ count = count % 32;
+
+ bits = __unsignedLongIntVal(self);
+ if (count > 0) {
+ bits = (bits << count) | (bits >> (32-count));
+ } else {
+ bits = (bits >> (-count)) | (bits << (32-(-count)));
+ }
#if __POINTER_SIZE__ == 8
- bits &= 0xFFFFFFFFL;
+ bits &= 0xFFFFFFFFL;
#endif
- RETURN (__MKUINT(bits));
+ RETURN (__MKUINT(bits));
}
%}.
^ self primitiveFailed
@@ -1448,21 +1383,21 @@
int count;
if (__isSmallInteger(shiftCount)) {
- count = __intVal(shiftCount);
- if (count >= 32) {
- RETURN (__mkSmallInteger(0));
- }
-
- bits = __unsignedLongIntVal(self);
- if (count > 0) {
- bits = bits << count;
- } else {
- bits = bits >> (-count);
- }
+ count = __intVal(shiftCount);
+ if (count >= 32) {
+ RETURN (__mkSmallInteger(0));
+ }
+
+ bits = __unsignedLongIntVal(self);
+ if (count > 0) {
+ bits = bits << count;
+ } else {
+ bits = bits >> (-count);
+ }
#if __POINTER_SIZE__ == 8
- bits &= 0xFFFFFFFFL;
+ bits &= 0xFFFFFFFFL;
#endif
- RETURN (__MKUINT(bits));
+ RETURN (__MKUINT(bits));
}
%}.
^ self primitiveFailed
@@ -1526,9 +1461,9 @@
unsigned INT swapped;
swapped = ( (__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[0]) << 24)
- | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[1]) << 16)
- | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[2]) << 8)
- | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[3]));
+ | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[1]) << 16)
+ | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[2]) << 8)
+ | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[3]));
RETURN (__MKUINT(swapped));
%}.
^ super byteSwapped32
@@ -1554,14 +1489,14 @@
unsigned INT swapped;
swappedHI = ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[0]) << 24)
- | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[1]) << 16)
- | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[2]) << 8)
- | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[3]));
+ | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[1]) << 16)
+ | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[2]) << 8)
+ | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[3]));
if (__byteArraySize(__INST(digitByteArray)) > 4) {
- swappedLO = ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[4]) << 24)
- | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[5]) << 16)
- | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[6]) << 8)
- | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[7]));
+ swappedLO = ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[4]) << 24)
+ | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[5]) << 16)
+ | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[6]) << 8)
+ | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[7]));
}
#if __POINTER_SIZE__ == 8
@@ -1621,16 +1556,16 @@
#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
digits := (self bitInvert + 1) digitBytes.
index > digits size ifTrue:[
- ^ 16rFF
+ ^ 16rFF
].
^ digits at:index.
@@ -1674,7 +1609,7 @@
otherwise least significant byte is first"
msbFlag ifTrue:[
- ^ digitByteArray copyReverse.
+ ^ digitByteArray copyReverse.
].
^ digitByteArray
@@ -1687,15 +1622,15 @@
Least significant byte is first!!"
sign > 0 ifTrue:[
- ^ digitByteArray
+ ^ digitByteArray
].
"answer the 2's complement"
^ (self bitInvert + 1) digitBytes.
- "
- 16r12345678901234567890 digitBytesSigned
- -16r12345678901234567890 digitBytesSigned
+ "
+ 16r12345678901234567890 digitBytesSigned
+ -16r12345678901234567890 digitBytesSigned
"
!
@@ -1718,7 +1653,7 @@
%}.
l := digitByteArray size.
[l ~~ 0 and:[(digitByteArray at:l) == 0]] whileTrue:[
- l := l - 1.
+ l := l - 1.
].
^ l
@@ -1770,12 +1705,12 @@
value := 0.
(sign == 0) ifFalse:[
- digitByteArray reverseDo:[:aDigit |
- value := (value times:256) + aDigit
- ].
- (sign < 0) ifTrue:[
- value := value negated
- ]
+ digitByteArray reverseDo:[:aDigit |
+ value := (value times:256) + aDigit
+ ].
+ (sign < 0) ifTrue:[
+ value := value negated
+ ]
].
^ value
!
@@ -1820,206 +1755,206 @@
OBJ t;
if (__INST(sign) == __mkSmallInteger(0)) {
- RETURN (__mkSmallInteger(0));
+ RETURN (__mkSmallInteger(0));
}
t = __INST(digitByteArray);
if (__isByteArray(t)) {
- unsigned char *__digitBytes = __ByteArrayInstPtr(t)->ba_element;
- int _idx, _idx0;
- INT _val;
-
- _idx = _idx0 = __byteArraySize(t);
- while ((_idx > 0) && (__digitBytes[_idx - 1] == 0)) {
- _idx--;
- }
+ unsigned char *__digitBytes = __ByteArrayInstPtr(t)->ba_element;
+ int _idx, _idx0;
+ INT _val;
+
+ _idx = _idx0 = __byteArraySize(t);
+ while ((_idx > 0) && (__digitBytes[_idx - 1] == 0)) {
+ _idx--;
+ }
#if __POINTER_SIZE__ == 8
- switch (_idx) {
- case 8:
- _val = __digitBytes[7];
- if (_val <= 0x40) {
- _val = (_val<<8);
- _val = (_val + __digitBytes[6]) << 8;
- _val = (_val + __digitBytes[5]) << 8;
- _val = (_val + __digitBytes[4]) << 8;
- _val = (_val + __digitBytes[3]) << 8;
- _val = (_val + __digitBytes[2]) << 8;
- _val = (_val + __digitBytes[1]) << 8;
- _val += __digitBytes[0];
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- if (__ISVALIDINTEGER(_val)) {
- RETURN (__mkSmallInteger(_val));
- }
- }
- break;
- case 7:
+ switch (_idx) {
+ case 8:
+ _val = __digitBytes[7];
+ if (_val <= 0x40) {
+ _val = (_val<<8);
+ _val = (_val + __digitBytes[6]) << 8;
+ _val = (_val + __digitBytes[5]) << 8;
+ _val = (_val + __digitBytes[4]) << 8;
+ _val = (_val + __digitBytes[3]) << 8;
+ _val = (_val + __digitBytes[2]) << 8;
+ _val = (_val + __digitBytes[1]) << 8;
+ _val += __digitBytes[0];
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ if (__ISVALIDINTEGER(_val)) {
+ RETURN (__mkSmallInteger(_val));
+ }
+ }
+ break;
+ case 7:
# if defined(__LSBFIRST__)
- _val = ((INT *)__digitBytes)[0] & 0x00FFFFFFFFFFFFFFL;
+ _val = ((INT *)__digitBytes)[0] & 0x00FFFFFFFFFFFFFFL;
# else
- _val = (__digitBytes[6]<<8);
- _val = (_val + __digitBytes[5]) << 8;
- _val = (_val + __digitBytes[4]) << 8;
- _val = (_val + __digitBytes[3]) << 8;
- _val = (_val + __digitBytes[2]) << 8;
- _val = (_val + __digitBytes[1]) << 8;
- _val += __digitBytes[0];
+ _val = (__digitBytes[6]<<8);
+ _val = (_val + __digitBytes[5]) << 8;
+ _val = (_val + __digitBytes[4]) << 8;
+ _val = (_val + __digitBytes[3]) << 8;
+ _val = (_val + __digitBytes[2]) << 8;
+ _val = (_val + __digitBytes[1]) << 8;
+ _val += __digitBytes[0];
# endif
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- RETURN (__mkSmallInteger(_val));
- case 6:
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ RETURN (__mkSmallInteger(_val));
+ case 6:
# if defined(__LSBFIRST__)
- _val = ((INT *)__digitBytes)[0] & 0x0000FFFFFFFFFFFFL;
+ _val = ((INT *)__digitBytes)[0] & 0x0000FFFFFFFFFFFFL;
# else
- _val = (__digitBytes[5]<<8);
- _val = (_val + __digitBytes[4]) << 8;
- _val = (_val + __digitBytes[3]) << 8;
- _val = (_val + __digitBytes[2]) << 8;
- _val = (_val + __digitBytes[1]) << 8;
- _val += __digitBytes[0];
+ _val = (__digitBytes[5]<<8);
+ _val = (_val + __digitBytes[4]) << 8;
+ _val = (_val + __digitBytes[3]) << 8;
+ _val = (_val + __digitBytes[2]) << 8;
+ _val = (_val + __digitBytes[1]) << 8;
+ _val += __digitBytes[0];
# endif
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- RETURN (__mkSmallInteger(_val));
- case 5:
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ RETURN (__mkSmallInteger(_val));
+ case 5:
# if defined(__LSBFIRST__)
- _val = ((INT *)__digitBytes)[0] & 0x000000FFFFFFFFFFL;
+ _val = ((INT *)__digitBytes)[0] & 0x000000FFFFFFFFFFL;
# else
- _val = (__digitBytes[4]<<8);
- _val = (_val + __digitBytes[3]) << 8;
- _val = (_val + __digitBytes[2]) << 8;
- _val = (_val + __digitBytes[1]) << 8;
- _val += __digitBytes[0];
+ _val = (__digitBytes[4]<<8);
+ _val = (_val + __digitBytes[3]) << 8;
+ _val = (_val + __digitBytes[2]) << 8;
+ _val = (_val + __digitBytes[1]) << 8;
+ _val += __digitBytes[0];
# endif
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- RETURN (__mkSmallInteger(_val));
- case 4:
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ RETURN (__mkSmallInteger(_val));
+ case 4:
# if defined(__LSBFIRST__)
- _val = ((INT *)__digitBytes)[0] & 0x00000000FFFFFFFFL;
+ _val = ((INT *)__digitBytes)[0] & 0x00000000FFFFFFFFL;
# else
- _val = (__digitBytes[3]<<8);
- _val = (_val + __digitBytes[2]) << 8;
- _val = (_val + __digitBytes[1]) << 8;
- _val += __digitBytes[0];
+ _val = (__digitBytes[3]<<8);
+ _val = (_val + __digitBytes[2]) << 8;
+ _val = (_val + __digitBytes[1]) << 8;
+ _val += __digitBytes[0];
# endif
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- RETURN (__mkSmallInteger(_val));
- case 3:
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ RETURN (__mkSmallInteger(_val));
+ case 3:
# if defined(__LSBFIRST__)
- _val = ((int *)__digitBytes)[0] & 0x00FFFFFF;
+ _val = ((int *)__digitBytes)[0] & 0x00FFFFFF;
# else
- _val = (__digitBytes[2]<<8);
- _val = (_val + __digitBytes[1]) << 8;
- _val += __digitBytes[0];
+ _val = (__digitBytes[2]<<8);
+ _val = (_val + __digitBytes[1]) << 8;
+ _val += __digitBytes[0];
# endif
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- RETURN (__mkSmallInteger(_val));
- case 2:
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ RETURN (__mkSmallInteger(_val));
+ case 2:
# if defined(__LSBFIRST__)
- _val = ((int *)__digitBytes)[0] & 0x0000FFFF;
+ _val = ((int *)__digitBytes)[0] & 0x0000FFFF;
# else
- _val = (__digitBytes[1]<<8) + __digitBytes[0];
+ _val = (__digitBytes[1]<<8) + __digitBytes[0];
# endif
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- RETURN (__mkSmallInteger(_val));
- case 1:
- _val = __digitBytes[0];
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- RETURN (__mkSmallInteger(_val));
- case 0:
- RETURN (__mkSmallInteger(0));
-
- }
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ RETURN (__mkSmallInteger(_val));
+ case 1:
+ _val = __digitBytes[0];
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ RETURN (__mkSmallInteger(_val));
+ case 0:
+ RETURN (__mkSmallInteger(0));
+
+ }
#else
- if (_idx <= 4) {
- if (_idx <= 2) {
- if (_idx == 0) {
- RETURN (__mkSmallInteger(0));
- }
- if (_idx == 1) {
- _val = __digitBytes[0];
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- RETURN (__mkSmallInteger(_val));
- }
+ if (_idx <= 4) {
+ if (_idx <= 2) {
+ if (_idx == 0) {
+ RETURN (__mkSmallInteger(0));
+ }
+ if (_idx == 1) {
+ _val = __digitBytes[0];
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ RETURN (__mkSmallInteger(_val));
+ }
# if defined(__LSBFIRST__)
- _val = ((int *)__digitBytes)[0] & 0x0000FFFF;
+ _val = ((int *)__digitBytes)[0] & 0x0000FFFF;
# else
- _val = (__digitBytes[1]<<8) + __digitBytes[0];
+ _val = (__digitBytes[1]<<8) + __digitBytes[0];
# endif
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- RETURN (__mkSmallInteger(_val));
- }
- if (_idx == 3) {
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ RETURN (__mkSmallInteger(_val));
+ }
+ if (_idx == 3) {
# if defined(__LSBFIRST__)
- _val = ((int *)__digitBytes)[0] & 0x00FFFFFF;
+ _val = ((int *)__digitBytes)[0] & 0x00FFFFFF;
# else
- _val = (((__digitBytes[2]<<8) + __digitBytes[1])<<8) + __digitBytes[0];
+ _val = (((__digitBytes[2]<<8) + __digitBytes[1])<<8) + __digitBytes[0];
# endif
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- RETURN (__mkSmallInteger(_val));
- }
- _val = __digitBytes[3];
- if (_val <= 0x40) {
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ RETURN (__mkSmallInteger(_val));
+ }
+ _val = __digitBytes[3];
+ if (_val <= 0x40) {
# if defined(__LSBFIRST__)
- _val = ((int *)__digitBytes)[0];
+ _val = ((int *)__digitBytes)[0];
# else
- _val = (((((_val<<8) + __digitBytes[2])<<8) + __digitBytes[1])<<8) + __digitBytes[0];
+ _val = (((((_val<<8) + __digitBytes[2])<<8) + __digitBytes[1])<<8) + __digitBytes[0];
# endif
- if (__INST(sign) == __mkSmallInteger(-1))
- _val = -_val;
- if (__ISVALIDINTEGER(_val)) {
- RETURN (__mkSmallInteger(_val));
- }
- }
- }
+ if (__INST(sign) == __mkSmallInteger(-1))
+ _val = -_val;
+ if (__ISVALIDINTEGER(_val)) {
+ RETURN (__mkSmallInteger(_val));
+ }
+ }
+ }
#endif
- if (_idx == _idx0) {
- RETURN (self);
- }
-
- /*
- * must copy & cut off some (zero)bytes
- */
- {
- OBJ newDigits;
- OBJ oldDigits;
-
- /*
- * careful - there is no context here to protect
- * the receiver ...
- */
- __PROTECT__(self);
- __PROTECT__(__INST(digitByteArray));
- newDigits = __BYTEARRAY_UNINITIALIZED_NEW_INT(_idx);
- __UNPROTECT__(oldDigits);
- __UNPROTECT__(self);
- if (newDigits) {
- bcopy(__ByteArrayInstPtr(oldDigits)->ba_element,
- __ByteArrayInstPtr(newDigits)->ba_element,
- _idx);
- __INST(digitByteArray) = newDigits; __STORE(self, newDigits);
- RETURN (self);
- }
- /*
- * allocation failed ...
- * ... fall through to trigger the error
- */
- }
+ if (_idx == _idx0) {
+ RETURN (self);
+ }
+
+ /*
+ * must copy & cut off some (zero)bytes
+ */
+ {
+ OBJ newDigits;
+ OBJ oldDigits;
+
+ /*
+ * careful - there is no context here to protect
+ * the receiver ...
+ */
+ __PROTECT__(self);
+ __PROTECT__(__INST(digitByteArray));
+ newDigits = __BYTEARRAY_UNINITIALIZED_NEW_INT(_idx);
+ __UNPROTECT__(oldDigits);
+ __UNPROTECT__(self);
+ if (newDigits) {
+ bcopy(__ByteArrayInstPtr(oldDigits)->ba_element,
+ __ByteArrayInstPtr(newDigits)->ba_element,
+ _idx);
+ __INST(digitByteArray) = newDigits; __STORE(self, newDigits);
+ RETURN (self);
+ }
+ /*
+ * allocation failed ...
+ * ... fall through to trigger the error
+ */
+ }
}
%}.
index0 := index := digitByteArray size.
[(index > 0) and:[(digitByteArray at:index) == 0]] whileTrue:[
- index := index - 1
+ index := index - 1
].
"/ ((index < SmallInteger maxBytes)
"/ or:[(index == SmallInteger maxBytes)
@@ -2033,7 +1968,7 @@
"/ ^ val * sign
"/ ].
(index ~~ index0) ifTrue:[
- digitByteArray := digitByteArray copyFrom:1 to:index
+ digitByteArray := digitByteArray copyFrom:1 to:index
].
^ self
!
@@ -2074,87 +2009,87 @@
overhead of producing any intermediate byte-arrays (and the scanning)
"
(aSmallInteger == 0) ifTrue: [
- digitByteArray := ByteArray with:0.
- sign := 0.
- ^ self
+ digitByteArray := ByteArray with:0.
+ sign := 0.
+ ^ self
].
(aSmallInteger < 0) ifTrue: [
- sign := -1.
- absValue := aSmallInteger negated
+ sign := -1.
+ absValue := aSmallInteger negated
] ifFalse: [
- sign := 1.
- absValue := aSmallInteger
+ sign := 1.
+ absValue := aSmallInteger
].
b1 := absValue bitAnd:16rFF.
absValue := absValue bitShift:-8.
absValue == 0 ifTrue:[
- digitByteArray := ByteArray with:b1
+ digitByteArray := ByteArray with:b1
] ifFalse:[
- b2 := absValue bitAnd:16rFF.
- absValue := absValue bitShift:-8.
- absValue == 0 ifTrue:[
- digitByteArray := ByteArray with:b1 with:b2
- ] ifFalse:[
- b3 := absValue bitAnd:16rFF.
- absValue := absValue bitShift:-8.
- absValue == 0 ifTrue:[
- digitByteArray := ByteArray with:b1 with:b2 with:b3
- ] ifFalse:[
- b4 := absValue bitAnd:16rFF.
- absValue := absValue bitShift:-8.
- absValue == 0 ifTrue:[
- digitByteArray := ByteArray with:b1 with:b2 with:b3 with:b4
- ] ifFalse:[
- b5 := absValue bitAnd:16rFF.
- absValue := absValue bitShift:-8.
- absValue == 0 ifTrue:[
- digitByteArray := ByteArray new:5.
- 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.
- ] ifFalse:[
- b6 := absValue bitAnd:16rFF.
- 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.
- ] 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.
- ] 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:8 put:absValue.
- ]
- ]
- ]
- ]
- ]
- ]
+ b2 := absValue bitAnd:16rFF.
+ absValue := absValue bitShift:-8.
+ absValue == 0 ifTrue:[
+ digitByteArray := ByteArray with:b1 with:b2
+ ] ifFalse:[
+ b3 := absValue bitAnd:16rFF.
+ absValue := absValue bitShift:-8.
+ absValue == 0 ifTrue:[
+ digitByteArray := ByteArray with:b1 with:b2 with:b3
+ ] ifFalse:[
+ b4 := absValue bitAnd:16rFF.
+ absValue := absValue bitShift:-8.
+ absValue == 0 ifTrue:[
+ digitByteArray := ByteArray with:b1 with:b2 with:b3 with:b4
+ ] ifFalse:[
+ b5 := absValue bitAnd:16rFF.
+ absValue := absValue bitShift:-8.
+ absValue == 0 ifTrue:[
+ digitByteArray := ByteArray new:5.
+ 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.
+ ] ifFalse:[
+ b6 := absValue bitAnd:16rFF.
+ 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.
+ ] 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.
+ ] 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:8 put:absValue.
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
]
"Modified: / 26.5.1999 / 22:18:14 / cg"
@@ -2168,41 +2103,41 @@
|otherSign|
(aNumber class == self class) ifTrue:[
- otherSign := aNumber sign.
-
- (sign > 0) ifTrue:[
- "I am positive"
- (otherSign > 0) ifTrue:[^ self absLess:aNumber].
- ^ false "aNumber is <= 0"
- ].
- "I am negative"
- (otherSign > 0) ifTrue:[^ true].
- (otherSign == 0) ifTrue:[^ true].
- ^ (aNumber absLess:self)
+ otherSign := aNumber sign.
+
+ (sign > 0) ifTrue:[
+ "I am positive"
+ (otherSign > 0) ifTrue:[^ self absLess:aNumber].
+ ^ false "aNumber is <= 0"
+ ].
+ "I am negative"
+ (otherSign > 0) ifTrue:[^ true].
+ (otherSign == 0) ifTrue:[^ true].
+ ^ (aNumber absLess:self)
].
(aNumber class == SmallInteger) ifTrue:[
- otherSign := aNumber sign.
-
- (sign > 0) ifTrue:[
- "I am positive"
- ^ false "aNumber is <= 0"
- ].
- (sign == 0) ifTrue:[
- (otherSign > 0) ifTrue:[^ true].
- ^ false
- ].
- "I am negative"
- ^ true
+ otherSign := aNumber sign.
+
+ (sign > 0) ifTrue:[
+ "I am positive"
+ ^ false "aNumber is <= 0"
+ ].
+ (sign == 0) ifTrue:[
+ (otherSign > 0) ifTrue:[^ true].
+ ^ false
+ ].
+ "I am negative"
+ ^ true
].
"/ hack for epsilon tests
(aNumber class == Float) ifTrue:[
- self negative ifTrue:[
- "/ I am a large negative; so my value is definitely below SmallInteger minVal
- aNumber >= SmallInteger minVal asFloat ifTrue:[^ true].
- ] ifFalse:[
- "/ I am a large positive; so my value is definitely above SmallInteger maxVal
- aNumber <= SmallInteger maxVal asFloat ifTrue:[^ false].
- ].
+ self negative ifTrue:[
+ "/ I am a large negative; so my value is definitely below SmallInteger minVal
+ aNumber >= SmallInteger minVal asFloat ifTrue:[^ true].
+ ] ifFalse:[
+ "/ I am a large positive; so my value is definitely above SmallInteger maxVal
+ aNumber <= SmallInteger maxVal asFloat ifTrue:[^ false].
+ ].
].
^ aNumber lessFromInteger:self
@@ -2217,17 +2152,17 @@
"/ speed up compare to 0
(aNumber == 0) ifTrue:[
- ^ sign == 0
+ ^ sign == 0
].
(aNumber class == self class) ifFalse:[
- "/
- "/ here, we depend on the fact, that largeinteger
- "/ results are always converted to smallInts, if possible.
- "/ therefore, a largeInt in the smallInt range is not allowed (possible)
- "/
- aNumber class == SmallInteger ifTrue:[^ false ].
- ^ aNumber equalFromInteger:self
+ "/
+ "/ here, we depend on the fact, that largeinteger
+ "/ results are always converted to smallInts, if possible.
+ "/ therefore, a largeInt in the smallInt range is not allowed (possible)
+ "/
+ aNumber class == SmallInteger ifTrue:[^ false ].
+ ^ aNumber equalFromInteger:self
].
(aNumber sign == sign) ifFalse:[^ false].
@@ -2242,19 +2177,19 @@
|otherSign|
(aNumber class == self class) ifFalse:[
- ^ (aNumber < self)
+ ^ (aNumber < self)
].
otherSign := aNumber sign.
(sign > 0) ifTrue:[
- "I am positive"
- (otherSign > 0) ifTrue:[^ aNumber absLess:self].
- ^ true "aNumber is <= 0"
+ "I am positive"
+ (otherSign > 0) ifTrue:[^ aNumber absLess:self].
+ ^ true "aNumber is <= 0"
].
(sign == 0) ifTrue:[
- "I am zero"
- (otherSign > 0) ifTrue:[^ false].
- ^ true
+ "I am zero"
+ (otherSign > 0) ifTrue:[^ false].
+ ^ true
].
"I am negative"
(otherSign > 0) ifTrue:[^ false].
@@ -2273,18 +2208,18 @@
l := digitByteArray size.
l >= 8 ifTrue:[
- h := h bitXor:(digitByteArray at:l).
- h := h bitXor:((digitByteArray at:l-1) bitShift:8).
- h := h bitXor:((digitByteArray at:l-2) bitShift:16).
- h := h bitXor:((digitByteArray at:l-3) bitShift:22).
- l >= 12 ifTrue:[
- m := l // 2.
- h := h bitXor:(digitByteArray at:m-1).
- h := h bitXor:((digitByteArray at:m) bitShift:8).
- h := h bitXor:((digitByteArray at:m+1) bitShift:16).
- h := h bitXor:((digitByteArray at:m+2) bitShift:22).
- ].
- ^ h
+ h := h bitXor:(digitByteArray at:l).
+ h := h bitXor:((digitByteArray at:l-1) bitShift:8).
+ h := h bitXor:((digitByteArray at:l-2) bitShift:16).
+ h := h bitXor:((digitByteArray at:l-3) bitShift:22).
+ l >= 12 ifTrue:[
+ m := l // 2.
+ h := h bitXor:(digitByteArray at:m-1).
+ h := h bitXor:((digitByteArray at:m) bitShift:8).
+ h := h bitXor:((digitByteArray at:m+1) bitShift:16).
+ h := h bitXor:((digitByteArray at:m+2) bitShift:22).
+ ].
+ ^ h
].
^ (h bitShift:3) + l
@@ -2309,22 +2244,22 @@
Return the result of 'anInteger - self'. The argument must be a SmallInteger."
anInteger > 0 ifTrue:[
- sign > 0 ifTrue:[
- ^ self absFastMinus:anInteger sign:-1
- ].
- ^ self absFastPlus:anInteger sign:1
+ sign > 0 ifTrue:[
+ ^ self absFastMinus:anInteger sign:-1
+ ].
+ ^ self absFastPlus:anInteger sign:1
].
anInteger == 0 ifTrue:[
- ^ self negated
+ ^ self negated
].
sign > 0 ifTrue:[
- ^ self absFastPlus:anInteger negated sign:-1
+ ^ self absFastPlus:anInteger negated sign:-1
].
self > anInteger ifTrue:[
- ^ self absFastMinus:anInteger asLargeInteger sign:-1
+ ^ self absFastMinus:anInteger asLargeInteger sign:-1
] ifFalse:[
- ^ anInteger asLargeInteger absFastMinus:self sign:-1
+ ^ anInteger asLargeInteger absFastMinus:self sign:-1
].
"
@@ -2344,7 +2279,7 @@
"sent when an integer does not know how to compare to the receiver, a largeInt"
|otherClass|
-
+
"/
"/ here, we depend on the fact, that largeinteger
"/ results are always converted to smallInts, if possible.
@@ -2353,8 +2288,8 @@
otherClass := anInteger class.
otherClass == SmallInteger ifTrue:[^ false ].
otherClass == self class ifTrue:[
- (anInteger sign == sign) ifFalse:[^ false].
- ^ self absEq:anInteger
+ (anInteger sign == sign) ifFalse:[^ false].
+ ^ self absEq:anInteger
].
^ super equalFromInteger:anInteger
!
@@ -2369,12 +2304,12 @@
"/ therefore, a largeInt in the smallInt range is not allowed (possible)
"/
(anInteger class == SmallInteger) ifTrue:[
- (sign > 0) ifTrue:[
- "I am positive - any largeInteger is larger than any smallInteger"
- ^ true "anInteger is <= 0"
- ].
- "I am negative - any negative largeInteger is smaller than any smallInteger"
- ^ false
+ (sign > 0) ifTrue:[
+ "I am positive - any largeInteger is larger than any smallInteger"
+ ^ true "anInteger is <= 0"
+ ].
+ "I am negative - any negative largeInteger is smaller than any smallInteger"
+ ^ false
].
^ super lessFromInteger:anInteger
!
@@ -2399,60 +2334,60 @@
num := anInteger abs.
SmallInteger maxBytes == 8 ifTrue:[
- (num > 16rFFFFFFFFFF) ifTrue:[
- "if num is too big (so that multiplying by a byte could create a Large)"
- ^ anInteger retry:#* coercing:self
- ].
- ] ifFalse:[
- (num > 16r3FFFFF) ifTrue:[
- "if num is too big (so that multiplying by a byte could create a Large)"
- ^ anInteger retry:#* coercing:self
- ].
+ (num > 16rFFFFFFFFFF) ifTrue:[
+ "if num is too big (so that multiplying by a byte could create a Large)"
+ ^ anInteger retry:#* coercing:self
+ ].
+ ] ifFalse:[
+ (num > 16r3FFFFF) ifTrue:[
+ "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:[
- val <= 16rFFFFFFFF ifTrue:[
- lResult := len + 6.
- ] ifFalse:[
- val <= 16rFFFFFFFFFF ifTrue:[
- lResult := len + 8.
- ] ifFalse:[
- val <= 16rFFFFFFFFFF ifTrue:[
- lResult := len + 10.
- ] ifFalse:[
- val <= 16rFFFFFFFFFFFF ifTrue:[
- lResult := len + 12.
- ] ifFalse:[
- lResult := len + 14.
- ]
- ]
- ]
- ]
- ]
- ]
+ val <= 16rFFFF ifTrue:[
+ lResult := len + 2
+ ] ifFalse:[
+ val <= 16rFFFFFF ifTrue:[
+ lResult := len + 4.
+ ] ifFalse:[
+ val <= 16rFFFFFFFF ifTrue:[
+ lResult := len + 6.
+ ] ifFalse:[
+ val <= 16rFFFFFFFFFF ifTrue:[
+ lResult := len + 8.
+ ] ifFalse:[
+ val <= 16rFFFFFFFFFF ifTrue:[
+ lResult := len + 10.
+ ] ifFalse:[
+ val <= 16rFFFFFFFFFFFF ifTrue:[
+ lResult := len + 12.
+ ] ifFalse:[
+ lResult := len + 14.
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
].
resultDigitByteArray := ByteArray uninitializedNew:lResult.
result := self class basicNew setDigits:resultDigitByteArray.
anInteger < 0 ifTrue:[
- sign > 0 ifTrue:[
- result setSign:-1
- ].
+ sign > 0 ifTrue:[
+ result setSign:-1
+ ].
] ifFalse:[
- sign < 0 ifTrue:[
- result setSign:sign
- ]
+ sign < 0 ifTrue:[
+ result setSign:sign
+ ]
].
ok := false.
@@ -2462,194 +2397,194 @@
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.
- * Late news: it actually hurts modern x86_64 cpus.
- * So only reenable for specific CPUs after concrete benchmarks.
- */
+ 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.
+ * Late news: it actually hurts modern x86_64 cpus.
+ * So only reenable for specific CPUs after concrete benchmarks.
+ */
#if 0
- while ((_l >= sizeof(INT)) && (((unsigned INT *)digitP)[0] == 0)) {
- ((unsigned INT *)resultP)[0] = 0;
- digitP += sizeof(INT);
- resultP += sizeof(INT);
- _l -= sizeof(INT);
- }
+ while ((_l >= sizeof(INT)) && (((unsigned INT *)digitP)[0] == 0)) {
+ ((unsigned INT *)resultP)[0] = 0;
+ digitP += sizeof(INT);
+ resultP += sizeof(INT);
+ _l -= sizeof(INT);
+ }
#endif
#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 64bit ints; can do it int-wise
- *
- * max: 0xFFFFFFFF * 0xFFFFFFFF -> 0xFFFFFFFE.0001
- * + maxCarry (0xFFFFFFFF) -> 0xFFFFFFFF.0000
- */
- while (_l >= (4+4+4+4)) {
- unsigned __t1, __t2, __t3, __t4;
- UINT64 _prod64a, _prod64b, _prod64c, _prod64d;
-
- __t1 = ((unsigned *)digitP)[0];
- _prod64a = (INT64)_v;
- _prod64a *= __t1;
- _prod64a += _carry;
- ((unsigned *)resultP)[0] = _prod64a /* & 0xFFFFFFFFL */;
- _carry = _prod64a >> 32;
-
- __t2 = ((unsigned *)digitP)[1];
- _prod64b = (INT64)_v;
- _prod64b *= __t2;
- _prod64b += _carry;
- ((unsigned *)resultP)[1] = _prod64b /* & 0xFFFFFFFFL */;
- _carry = _prod64b >> 32;
-
- __t3 = ((unsigned *)digitP)[2];
- _prod64c = (INT64)_v;
- _prod64c *= __t3;
- _prod64c += _carry;
- ((unsigned *)resultP)[2] = _prod64c /* & 0xFFFFFFFFL */;
- _carry = _prod64c >> 32;
-
- __t4 = ((unsigned *)digitP)[3];
- _prod64d = (INT64)_v;
- _prod64d *= __t4;
- _prod64d += _carry;
- ((unsigned *)resultP)[3] = _prod64d /* & 0xFFFFFFFFL */;
- _carry = _prod64d >> 32;
-
- digitP += (4+4+4+4);
- resultP += (4+4+4+4);
- _l -= (4+4+4+4);
- }
- while (_l >= 4) {
- unsigned __t;
- UINT64 _prod64;
-
- __t = ((unsigned *)digitP)[0];
- _prod64 = (INT64)_v;
- _prod64 *= __t;
- _prod64 += _carry;
- ((unsigned *)resultP)[0] = _prod64 /* & 0xFFFFFFFFL */;
- _carry = _prod64 >> 32;
- digitP += 4;
- resultP += 4;
- _l -= 4;
- }
- if (_l >= 2) {
- unsigned short __t;
- UINT64 _prod64;
-
- __t = ((unsigned short *)digitP)[0];
- _prod64 = (INT64)_v;
- _prod64 *= __t;
- _prod64 += _carry;
- ((unsigned short *)resultP)[0] = _prod64 /* & 0xFFFF */;
- _carry = _prod64 >> 16;
- digitP += 2;
- resultP += 2;
- _l -= 2;
- }
- if (_l > 0) {
- UINT64 _prod64;
- _prod64 = *digitP++ * _v + _carry;
- *resultP++ = _prod64 /* & 0xFF */;
- _carry = _prod64 >> 8;
- _l--;
- }
- }
+ if (_v <= 0xFFFFFFFFL) {
+ /* have 64bit ints; can do it int-wise
+ *
+ * max: 0xFFFFFFFF * 0xFFFFFFFF -> 0xFFFFFFFE.0001
+ * + maxCarry (0xFFFFFFFF) -> 0xFFFFFFFF.0000
+ */
+ while (_l >= (4+4+4+4)) {
+ unsigned __t1, __t2, __t3, __t4;
+ UINT64 _prod64a, _prod64b, _prod64c, _prod64d;
+
+ __t1 = ((unsigned *)digitP)[0];
+ _prod64a = (INT64)_v;
+ _prod64a *= __t1;
+ _prod64a += _carry;
+ ((unsigned *)resultP)[0] = _prod64a /* & 0xFFFFFFFFL */;
+ _carry = _prod64a >> 32;
+
+ __t2 = ((unsigned *)digitP)[1];
+ _prod64b = (INT64)_v;
+ _prod64b *= __t2;
+ _prod64b += _carry;
+ ((unsigned *)resultP)[1] = _prod64b /* & 0xFFFFFFFFL */;
+ _carry = _prod64b >> 32;
+
+ __t3 = ((unsigned *)digitP)[2];
+ _prod64c = (INT64)_v;
+ _prod64c *= __t3;
+ _prod64c += _carry;
+ ((unsigned *)resultP)[2] = _prod64c /* & 0xFFFFFFFFL */;
+ _carry = _prod64c >> 32;
+
+ __t4 = ((unsigned *)digitP)[3];
+ _prod64d = (INT64)_v;
+ _prod64d *= __t4;
+ _prod64d += _carry;
+ ((unsigned *)resultP)[3] = _prod64d /* & 0xFFFFFFFFL */;
+ _carry = _prod64d >> 32;
+
+ digitP += (4+4+4+4);
+ resultP += (4+4+4+4);
+ _l -= (4+4+4+4);
+ }
+ while (_l >= 4) {
+ unsigned __t;
+ UINT64 _prod64;
+
+ __t = ((unsigned *)digitP)[0];
+ _prod64 = (INT64)_v;
+ _prod64 *= __t;
+ _prod64 += _carry;
+ ((unsigned *)resultP)[0] = _prod64 /* & 0xFFFFFFFFL */;
+ _carry = _prod64 >> 32;
+ digitP += 4;
+ resultP += 4;
+ _l -= 4;
+ }
+ if (_l >= 2) {
+ unsigned short __t;
+ UINT64 _prod64;
+
+ __t = ((unsigned short *)digitP)[0];
+ _prod64 = (INT64)_v;
+ _prod64 *= __t;
+ _prod64 += _carry;
+ ((unsigned short *)resultP)[0] = _prod64 /* & 0xFFFF */;
+ _carry = _prod64 >> 16;
+ digitP += 2;
+ resultP += 2;
+ _l -= 2;
+ }
+ if (_l > 0) {
+ UINT64 _prod64;
+ _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 */
@@ -2660,80 +2595,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;
}
%}.
"
@@ -2741,21 +2676,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
!
@@ -2765,16 +2700,16 @@
Return the sum of the receiver and the argument, (which must be a SmallInteger)"
anInteger > 0 ifTrue:[
- sign > 0 ifTrue:[
- ^ self absFastPlus:anInteger sign:1
- ].
- ^ self absFastMinus:anInteger sign:-1
+ sign > 0 ifTrue:[
+ ^ self absFastPlus:anInteger sign:1
+ ].
+ ^ self absFastMinus:anInteger sign:-1
].
anInteger == 0 ifTrue:[
- ^ self
+ ^ self
].
sign > 0 ifTrue:[
- ^ self absFastMinus:anInteger sign:1
+ ^ self absFastMinus:anInteger sign:1
].
^ self absFastPlus:anInteger sign:-1
@@ -2831,6 +2766,218 @@
!LargeInteger methodsFor:'private'!
+absDestructiveSubtract:aLargeInteger
+ "private helper for division:
+ destructively subtract aLargeInteger from myself
+ AND return true, if the result is non-zero, false otherwise.
+ (i.e. this method has both a return value and a side-effect on the receiver)
+ Does not care about the signs of the receiver and argument
+ The receiver must be >= the argument.
+ The receiver must be a temporary scratch-number"
+
+ |otherDigitByteArray
+ len1 "{ Class: SmallInteger }"
+ len2 "{ Class: SmallInteger }"
+ index "{ Class: SmallInteger }"
+ borrow "{ Class: SmallInteger }"
+ diff "{ Class: SmallInteger }"
+ notZero
+ |
+
+ notZero := false.
+ len1 := digitByteArray size.
+ otherDigitByteArray := aLargeInteger digitBytes.
+ len2 := otherDigitByteArray size.
+ len2 > len1 ifTrue:[
+ [(otherDigitByteArray at:len2) == 0] whileTrue:[
+ len2 := len2 - 1
+ ].
+ len2 > len1 ifTrue:[
+ self error:'operation failed' "/ may not be called that way
+ ].
+ ].
+ "/ knowing that len2 is <= len1
+%{
+
+ OBJ _digitByteArray = __INST(digitByteArray);
+
+ if (__isByteArray(_digitByteArray)
+ && __isByteArray(otherDigitByteArray)) {
+ int _len1 = __intVal(len1),
+ _len2 = __intVal(len2);
+ unsigned char *_myDigits, *_otherDigits;
+ int _index = 1, _borrow = 0;
+ INT _diff;
+ int anyBitNonZero = 0;
+
+ _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+ _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+
+#if defined(__LSBFIRST__)
+# if __POINTER_SIZE__ == 8
+ {
+ int _len2Q;
+ /*
+ * subtract int-wise
+ */
+ _len2Q = _len2-4;
+ while (_index <= _len2Q) {
+ /* do not combine the expression below (may lead to unsigned result on some machines) */
+ _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 += 0x100000000; */
+ }
+ ((unsigned int *)(_myDigits+_index-1))[0] = _diff;
+ anyBitNonZero |= (_diff & 0xFFFFFFFFL);
+ _index += 4;
+ }
+ }
+# endif
+
+ /*
+ * subtract short-wise
+ */
+ while (_index < _len2) {
+ /* do not combine the expression below (may lead to unsigned result on some machines */
+ _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 *)(_myDigits+_index-1))[0] = _diff;
+ anyBitNonZero |= (_diff & 0xFFFF);
+ _index += 2;
+ }
+
+ if (_index <= _len2) {
+ /*
+ * cannot continue with shorts - there is an odd number of
+ * bytes in the minuent
+ */
+ } else {
+ while (_index < _len1) {
+ /* do not combine the expression below (may lead to unsigned result on some machines */
+ _diff = ((unsigned short *)(_myDigits+_index-1))[0];
+ _diff -= _borrow;
+ if (_diff >= 0) {
+ /* _borrow = 0; */
+ ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
+ anyBitNonZero |= (_diff & 0xFFFF);
+ _index += 2;
+ while (_index < _len1) {
+ anyBitNonZero |= ((unsigned short *)(_myDigits+_index-1))[0];
+ if (anyBitNonZero) {
+ RETURN (true);
+ }
+ _index += 2;
+ }
+ /* last odd index */
+ if (_index <= _len1) {
+ anyBitNonZero |= _myDigits[_index - 1];;
+ if (anyBitNonZero) {
+ RETURN (true);
+ }
+ _index++;
+ }
+ RETURN (anyBitNonZero ? true : false);
+ }
+ _borrow = 1;
+ /* _diff += 0x10000; */
+
+ ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
+ anyBitNonZero |= (_diff & 0xFFFF);
+ _index += 2;
+ }
+ }
+#endif
+ /*
+ * subtract byte-wise
+ */
+ while (_index <= _len2) {
+ /* do not combine the expression below (may lead to unsigned result on some machines */
+ _diff = _myDigits[_index - 1];
+ _diff -= _otherDigits[_index - 1];
+ _diff -= _borrow;
+ if (_diff >= 0) {
+ _borrow = 0;
+ } else {
+ _borrow = 1;
+ /* _diff += 0x100; */
+ }
+ _myDigits[_index - 1] = _diff;
+ anyBitNonZero |= (_diff & 0xFF);
+ _index++;
+ }
+
+ while (_index <= _len1) {
+ /* do not combine the expression below (may lead to unsigned result on some machines */
+ _diff = _myDigits[_index - 1];
+ _diff -= _borrow;
+ if (_diff >= 0) {
+ /* _borrow = 0; */
+ _myDigits[_index - 1] = _diff;
+ anyBitNonZero |= (_diff & 0xFF);
+ _index++;
+ while (_index <= _len1) {
+ anyBitNonZero |= _myDigits[_index - 1];
+ if (anyBitNonZero) {
+ RETURN (true);
+ }
+ _index++;
+ }
+ break;
+ }
+ _borrow = 1;
+ /* _diff += 0x100; */
+
+ _myDigits[_index - 1] = _diff;
+ anyBitNonZero |= (_diff & 0xFF);
+ _index++;
+ }
+ RETURN (anyBitNonZero ? true : false);
+ }
+%}.
+
+ index := 1.
+ borrow := 0.
+
+ [index <= len1] whileTrue:[
+ diff := borrow.
+ diff := diff + (digitByteArray basicAt:index).
+ index <= len2 ifTrue:[
+ diff := diff - (otherDigitByteArray basicAt:index).
+ ].
+
+ "/ workaround for gcc code generator bug
+ (diff >= 0) ifTrue:[
+ borrow := 0
+ ] ifFalse:[
+ borrow := -1.
+ diff := diff + 16r100
+ ].
+ diff ~~ 0 ifTrue:[
+ notZero := true
+ ].
+ digitByteArray basicAt:index put:diff.
+ index := index + 1
+ ].
+
+ ^ notZero
+
+ "Created: / 5.11.1996 / 16:23:47 / cg"
+ "Modified: / 5.11.1996 / 18:56:50 / cg"
+ "Modified: / 27.4.1999 / 18:08:23 / stefan"
+!
+
absDivMod:anInteger
"return an array with two LargeIntegers representing
abs(self) // abs(theArgument) and abs(self) \\ abs(theArgument).
@@ -2839,25 +2986,34 @@
|dividend divisor
quo digits
+ divModOrNil
shift "{ Class: SmallInteger }" |
anInteger == 0 ifTrue:[
- ^ ZeroDivide raiseRequestWith:thisContext
+ ^ ZeroDivide raiseRequestWith:thisContext
].
- self = anInteger ifTrue:[
- ^ Array with:1 with:0
+ anInteger class == SmallInteger ifTrue:[
+ divisor := anInteger abs.
+ divModOrNil := self absFastDivMod:divisor.
+ divModOrNil notNil ifTrue:[^ divModOrNil].
+ divisor := divisor asLargeInteger.
+ ] ifFalse:[
+ self = anInteger ifTrue:[
+ ^ Array with:1 with:0
+ ].
+ divisor := anInteger.
].
- shift := self highBit - anInteger highBit.
+ shift := self highBit - divisor highBit.
dividend := self class digitBytes:digitByteArray copy. "/ self simpleDeepCopy sign:1.
shift < 0 ifTrue:[
- ^ Array with:0 with:dividend compressed.
+ ^ Array with:0 with:dividend compressed.
].
shift == 0 ifTrue:[
- divisor := self class digitBytes:(anInteger digitBytes copy). "/ anInteger simpleDeepCopy.
+ divisor := self class digitBytes:(divisor digitBytes copy). "/ anInteger simpleDeepCopy.
] ifFalse:[
- divisor := anInteger bitShift:shift.
+ divisor := divisor bitShift:shift.
].
quo := self class basicNew numberOfDigits:((shift // 8) + 1).
@@ -2865,14 +3021,14 @@
shift := shift + 1.
[shift > 0] whileTrue:[
- (dividend absLess:divisor) ifFalse:[
- digits bitSetAt:shift.
- (dividend absSubtract: divisor) ifFalse:[ "result == 0"
- ^ Array with:quo compressed with:0
- ].
- ].
- shift := shift - 1.
- divisor := divisor div2.
+ (dividend absLess:divisor) ifFalse:[
+ digits bitSetAt:shift.
+ (dividend absDestructiveSubtract: divisor) ifFalse:[ "result == 0"
+ ^ Array with:quo compressed with:0
+ ].
+ ].
+ shift := shift - 1.
+ divisor := divisor div2.
].
^ Array with:quo compressed with:dividend compressed
@@ -2900,60 +3056,60 @@
%{ /* NOCONTEXT */
if (__isLargeInteger(aLargeInteger)) {
- OBJ _digitByteArray = __INST(digitByteArray);
- OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
-
- if (__isByteArray(_digitByteArray)
- && __isByteArray(_otherDigitByteArray)) {
- INT _myLen = __byteArraySize(_digitByteArray);
- INT _otherLen = __byteArraySize(_otherDigitByteArray);
-
- unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
- unsigned char *_myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
-
- if (_myLen == _otherLen) {
+ OBJ _digitByteArray = __INST(digitByteArray);
+ OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
+
+ if (__isByteArray(_digitByteArray)
+ && __isByteArray(_otherDigitByteArray)) {
+ INT _myLen = __byteArraySize(_digitByteArray);
+ INT _otherLen = __byteArraySize(_otherDigitByteArray);
+
+ unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
+ unsigned char *_myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+
+ if (_myLen == _otherLen) {
tryAgain:
- while (_myLen >= (sizeof(INT)*4)) {
- if ( ((unsigned INT *)_myDigits)[0] != ((unsigned INT *)_otherDigits)[0]) {
- RETURN(false);
- }
- if ( ((unsigned INT *)_myDigits)[1] != ((unsigned INT *)_otherDigits)[1]) {
- RETURN(false);
- }
- if ( ((unsigned INT *)_myDigits)[2] != ((unsigned INT *)_otherDigits)[2]) {
- RETURN(false);
- }
- if ( ((unsigned INT *)_myDigits)[3] != ((unsigned INT *)_otherDigits)[3]) {
- RETURN(false);
- }
- _myDigits += sizeof(INT)*4;
- _otherDigits += sizeof(INT)*4;
- _myLen -= sizeof(INT)*4;
- }
- while (_myLen >= (sizeof(INT))) {
- if ( *(unsigned INT *)_myDigits != *(unsigned INT *)_otherDigits) {
- RETURN(false);
- }
- _myDigits += sizeof(INT);
- _otherDigits += sizeof(INT);
- _myLen -= sizeof(INT);
- }
- while (_myLen > 0) {
- if ( *_myDigits != *_otherDigits) {
- RETURN(false);
- }
- _myDigits++;
- _otherDigits++;
- _myLen--;
- }
- RETURN(true);
- }
- /* care for unnormalized ints */
- while ((_myLen > 0) && (_myDigits[_myLen-1] == 0)) _myLen--;
- while ((_otherLen > 0) && (_otherDigits[_otherLen-1] == 0)) _otherLen--;
- if (_myLen == _otherLen) goto tryAgain;
- RETURN(false);
- }
+ while (_myLen >= (sizeof(INT)*4)) {
+ if ( ((unsigned INT *)_myDigits)[0] != ((unsigned INT *)_otherDigits)[0]) {
+ RETURN(false);
+ }
+ if ( ((unsigned INT *)_myDigits)[1] != ((unsigned INT *)_otherDigits)[1]) {
+ RETURN(false);
+ }
+ if ( ((unsigned INT *)_myDigits)[2] != ((unsigned INT *)_otherDigits)[2]) {
+ RETURN(false);
+ }
+ if ( ((unsigned INT *)_myDigits)[3] != ((unsigned INT *)_otherDigits)[3]) {
+ RETURN(false);
+ }
+ _myDigits += sizeof(INT)*4;
+ _otherDigits += sizeof(INT)*4;
+ _myLen -= sizeof(INT)*4;
+ }
+ while (_myLen >= (sizeof(INT))) {
+ if ( *(unsigned INT *)_myDigits != *(unsigned INT *)_otherDigits) {
+ RETURN(false);
+ }
+ _myDigits += sizeof(INT);
+ _otherDigits += sizeof(INT);
+ _myLen -= sizeof(INT);
+ }
+ while (_myLen > 0) {
+ if ( *_myDigits != *_otherDigits) {
+ RETURN(false);
+ }
+ _myDigits++;
+ _otherDigits++;
+ _myLen--;
+ }
+ RETURN(true);
+ }
+ /* care for unnormalized ints */
+ while ((_myLen > 0) && (_myDigits[_myLen-1] == 0)) _myLen--;
+ while ((_otherLen > 0) && (_otherDigits[_otherLen-1] == 0)) _otherLen--;
+ if (_myLen == _otherLen) goto tryAgain;
+ RETURN(false);
+ }
}
%}.
@@ -2967,17 +3123,17 @@
"/ numbers to be compared ...
[(digitByteArray basicAt:len1) == 0] whileTrue:[
- len1 := len1 - 1
+ len1 := len1 - 1
].
[(otherDigitByteArray basicAt:len2) == 0] whileTrue:[
- len2 := len2 - 1
+ len2 := len2 - 1
].
(len1 ~~ len2) ifTrue:[^ false].
[len1 > 0] whileTrue:[
- d1 := digitByteArray basicAt:len1.
- d2 := otherDigitByteArray basicAt:len1.
- (d1 ~~ d2) ifTrue:[^ false].
- len1 := len1 - 1
+ d1 := digitByteArray basicAt:len1.
+ d2 := otherDigitByteArray basicAt:len1.
+ (d1 ~~ d2) ifTrue:[^ false].
+ len1 := len1 - 1
].
^ true
@@ -2986,8 +3142,9 @@
absFastDivMod:aPositiveSmallInteger
"return an array with two LargeIntegers representing
- abs(self) // aPositiveSmallInteger and
- abs(self) \\ aPositiveSmallInteger."
+ abs(self) // aPositiveSmallInteger and
+ abs(self) \\ aPositiveSmallInteger
+ or nil, if not computed by optimized code"
|tmp1 "{ Class: SmallInteger }"
prevRest "{ Class: SmallInteger }"
@@ -2996,12 +3153,12 @@
ok|
aPositiveSmallInteger == 0 ifTrue:[
- ^ ZeroDivide raiseRequestWith:thisContext
+ ^ ZeroDivide raiseRequestWith:thisContext
].
"This cannot happen (if always normalized)
self < aPositiveSmallInteger ifTrue:[
- ^ Array with:0 with:self
+ ^ Array with:0 with:self
].
"
count := digitByteArray size.
@@ -3016,123 +3173,130 @@
if (__isByteArray(__digits)
&& __isByteArray(newDigitByteArray)
&& __bothSmallInteger(count, aPositiveSmallInteger)) {
- unsigned INT rest = 0;
- int index = __intVal(count);
- int index0;
- unsigned INT divisor = __intVal(aPositiveSmallInteger);
- unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element;
- unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element;
-
- index0 = index - 1;
+ unsigned INT rest = 0;
+ int index = __intVal(count);
+ int index0;
+ unsigned INT divisor = __intVal(aPositiveSmallInteger);
+ unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element;
+ unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element;
+
+ index0 = index - 1;
+
+ // at least one byte of value must remain when dividing
+# if (__POINTER_SIZE__ == 8)
+ if (divisor > 0xFFFFFFFFFFFFFF) RETURN(nil);
+# else
+ if (divisor > 0xFFFFFF) RETURN(nil);
+# endif
# if (__POINTER_SIZE__ == 8)
- if (sizeof(int) == 4) {
- /*
- * divide int-wise
- */
- if (divisor <= 0xFFFFFFFF) {
- if ((index & 3) == 0) { /* even number of int32's */
- while (index > 3) {
- unsigned INT t;
- unsigned INT div;
-
- index -= 4;
+ if (sizeof(int) == 4) {
+ /*
+ * divide int-wise
+ */
+ if (divisor <= 0xFFFFFFFF) {
+ if ((index & 3) == 0) { /* even number of int32's */
+ while (index > 3) {
+ unsigned INT t;
+ unsigned INT div;
+
+ index -= 4;
# if defined(__LSBFIRST__)
- t = *((unsigned int *)(&digitBytes[index]));
+ t = *((unsigned int *)(&digitBytes[index]));
# else
- t = digitBytes[index+3];
- t = (t << 8) | digitBytes[index+2];
- t = (t << 8) | digitBytes[index+1];
- t = (t << 8) | digitBytes[index];
+ t = digitBytes[index+3];
+ t = (t << 8) | digitBytes[index+2];
+ t = (t << 8) | digitBytes[index+1];
+ t = (t << 8) | digitBytes[index];
# endif
- t = t | (rest << 32);
- div = t / divisor;
- rest = t % divisor;
+ t = t | (rest << 32);
+ div = t / divisor;
+ rest = t % divisor;
# if defined(__LSBFIRST__)
- *((unsigned int *)(&resultBytes[index])) = (div & 0xFFFFFFFF);
+ *((unsigned int *)(&resultBytes[index])) = (div & 0xFFFFFFFF);
# else
- resultBytes[index+3] = div >> 24;
- resultBytes[index+2] = div >> 16;
- resultBytes[index+1] = div >> 8;
- resultBytes[index] = div /* & 0xFF */;
+ resultBytes[index+3] = div >> 24;
+ resultBytes[index+2] = div >> 16;
+ resultBytes[index+1] = div >> 8;
+ resultBytes[index] = div /* & 0xFF */;
# endif
- }
- }
- }
- }
+ }
+ }
+ }
+ }
#endif
- /*
- * divide short-wise
- */
- if (divisor <= 0xFFFF) {
- if ((index & 1) == 0) { /* even number of bytes */
- while (index > 1) {
- unsigned INT t;
- unsigned INT div;
-
- index -= 2;
+ /*
+ * divide short-wise
+ */
+ if (divisor <= 0xFFFF) {
+ if ((index & 1) == 0) { /* even number of bytes */
+ while (index > 1) {
+ unsigned INT t;
+ unsigned INT div;
+
+ index -= 2;
#if defined(__LSBFIRST__)
- t = *((unsigned short *)(&digitBytes[index]));
+ t = *((unsigned short *)(&digitBytes[index]));
#else
- t = digitBytes[index+1];
- t = (t << 8) | digitBytes[index];
+ t = digitBytes[index+1];
+ t = (t << 8) | digitBytes[index];
#endif
- t = t | (rest << 16);
- div = t / divisor;
- rest = t % divisor;
+ t = t | (rest << 16);
+ div = t / divisor;
+ rest = t % divisor;
#if defined(__LSBFIRST__)
- *((unsigned short *)(&resultBytes[index])) = (div & 0xFFFF);
+ *((unsigned short *)(&resultBytes[index])) = (div & 0xFFFF);
#else
- resultBytes[index+1] = div >> 8;
- resultBytes[index] = div /* & 0xFF */;
+ resultBytes[index+1] = div >> 8;
+ resultBytes[index] = div /* & 0xFF */;
#endif
- }
- }
- }
- while (index > 0) {
- unsigned INT t;
-
- index--;
- t = digitBytes[index];
- t = t | (rest << 8);
- resultBytes[index] = t / divisor;
- rest = t % divisor;
- }
- prevRest = __mkSmallInteger(rest);
-
- /*
- * no need to normalize ?
- */
- index = index0;
- while ((index >= sizeof(INT)) && (resultBytes[index]==0)) {
- index--;
- }
-
- if (index == index0) {
- if (index > sizeof(INT)) {
- RETURN ( __ARRAY_WITH2(result, prevRest));
- }
- if ((index == sizeof(INT))
- && resultBytes[index0] >= 0x40) {
- RETURN ( __ARRAY_WITH2(result, prevRest));
- }
- }
-
- /*
- * must compress
- */
- ok = true;
+ }
+ }
+ }
+ while (index > 0) {
+ unsigned INT t;
+
+ index--;
+ t = digitBytes[index];
+ t = t | (rest << 8);
+ resultBytes[index] = t / divisor;
+ rest = t % divisor;
+ }
+ prevRest = __mkSmallInteger(rest);
+
+ /*
+ * no need to normalize ?
+ */
+ index = index0;
+ while ((index >= sizeof(INT)) && (resultBytes[index]==0)) {
+ index--;
+ }
+
+ if (index == index0) {
+ if (index > sizeof(INT)) {
+ RETURN ( __ARRAY_WITH2(result, prevRest));
+ }
+ if ((index == sizeof(INT))
+ && resultBytes[index0] >= 0x40) {
+ RETURN ( __ARRAY_WITH2(result, prevRest));
+ }
+ }
+
+ /*
+ * must compress
+ */
+ ok = true;
}
%}.
"
slow code - not normally reached
(could also do a primitiveFailure here)
"
- ok ifFalse:[
- ^ self absDivMod:(self class value:aPositiveSmallInteger).
+ ok ifTrue:[
+ ^ Array with:(result compressed) with:prevRest
].
-
- ^ Array with:(result compressed) with:prevRest
+ ^ nil
+
"
16r123412341234 asLargeInteger absDivMod:(LargeInteger value:10)
@@ -3141,6 +3305,8 @@
((666666666666666666 asLargeInteger absFastDivMod:16r3))
((1666666666 asLargeInteger absFastDivMod:16r3))
"
+
+ "Modified: / 26-02-2016 / 19:27:13 / cg"
!
absFastMinus:aSmallInteger sign:newSign
@@ -3161,7 +3327,7 @@
((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.
@@ -3175,123 +3341,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
@@ -3326,7 +3492,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.
@@ -3335,18 +3501,18 @@
"/ 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
%}
].
@@ -3358,307 +3524,307 @@
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
@@ -3680,58 +3846,58 @@
#if defined(__LSBFIRST__)
if (__isByteArray(__INST(digitByteArray))
&& __isLargeInteger(aLargeInteger)) {
- OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
-
- if (__isByteArray(_otherDigitByteArray)) {
- unsigned char *_myDigits = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
- unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
- INT _myLen = __byteArraySize(__INST(digitByteArray));
- INT _otherLen = __byteArraySize(_otherDigitByteArray);
-
- if (_myLen == __POINTER_SIZE__) {
- if (_otherLen == __POINTER_SIZE__) {
- unsigned INT _myVal = *((unsigned INT *)_myDigits);
- unsigned INT _otherVal = *((unsigned INT *)_otherDigits);
- RETURN( (_myVal < _otherVal) ? true : false );
- }
- }
+ OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
+
+ if (__isByteArray(_otherDigitByteArray)) {
+ unsigned char *_myDigits = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
+ unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
+ INT _myLen = __byteArraySize(__INST(digitByteArray));
+ INT _otherLen = __byteArraySize(_otherDigitByteArray);
+
+ if (_myLen == __POINTER_SIZE__) {
+ if (_otherLen == __POINTER_SIZE__) {
+ unsigned INT _myVal = *((unsigned INT *)_myDigits);
+ unsigned INT _otherVal = *((unsigned INT *)_otherDigits);
+ RETURN( (_myVal < _otherVal) ? true : false );
+ }
+ }
# if defined(UINT64) && (__POINTER_SIZE__ != 8)
- if (_myLen == __POINTER_SIZE__) {
- if (_otherLen <= 8) {
- UINT64 _myVal = (UINT64)(*((UINT *)_myDigits));
- UINT64 _otherVal = *((UINT64 *)_otherDigits);
- RETURN( (_myVal < _otherVal) ? true : false );
- }
- } else {
- if (_myLen <= 8) {
- if (_otherLen <= 8) {
- UINT64 _myVal = (*((UINT64 *)_myDigits));
- UINT64 _otherVal = *((UINT64 *)_otherDigits);
- RETURN( (_myVal < _otherVal) ? true : false );
- }
- if (_otherLen == __POINTER_SIZE__) {
- UINT64 _myVal = (*((UINT64 *)_myDigits));
- UINT64 _otherVal = (UINT64) *((UINT *)_otherDigits);
- RETURN( (_myVal < _otherVal) ? true : false );
- }
- }
- }
+ if (_myLen == __POINTER_SIZE__) {
+ if (_otherLen <= 8) {
+ UINT64 _myVal = (UINT64)(*((UINT *)_myDigits));
+ UINT64 _otherVal = *((UINT64 *)_otherDigits);
+ RETURN( (_myVal < _otherVal) ? true : false );
+ }
+ } else {
+ if (_myLen <= 8) {
+ if (_otherLen <= 8) {
+ UINT64 _myVal = (*((UINT64 *)_myDigits));
+ UINT64 _otherVal = *((UINT64 *)_otherDigits);
+ RETURN( (_myVal < _otherVal) ? true : false );
+ }
+ if (_otherLen == __POINTER_SIZE__) {
+ UINT64 _myVal = (*((UINT64 *)_myDigits));
+ UINT64 _otherVal = (UINT64) *((UINT *)_otherDigits);
+ RETURN( (_myVal < _otherVal) ? true : false );
+ }
+ }
+ }
# endif /* UINT64 */
- while ((_myLen > 0) && (_myDigits[_myLen-1] == 0)) _myLen--;
- while ((_otherLen > 0) && (_otherDigits[_otherLen-1] == 0)) _otherLen--;
- if (_myLen < _otherLen) { RETURN( true ); }
- if (_myLen > _otherLen) { RETURN (false ); }
- while (_myLen-- > 0) {
- unsigned char _d1 = _myDigits[_myLen];
- unsigned char _d2 = _otherDigits[_myLen];
-
- if (_d1 != _d2) {
- if (_d1 < _d2) { RETURN( true ); }
- RETURN (false );
- }
- }
- RETURN (false );
- }
+ while ((_myLen > 0) && (_myDigits[_myLen-1] == 0)) _myLen--;
+ while ((_otherLen > 0) && (_otherDigits[_otherLen-1] == 0)) _otherLen--;
+ if (_myLen < _otherLen) { RETURN( true ); }
+ if (_myLen > _otherLen) { RETURN (false ); }
+ while (_myLen-- > 0) {
+ unsigned char _d1 = _myDigits[_myLen];
+ unsigned char _d2 = _otherDigits[_myLen];
+
+ if (_d1 != _d2) {
+ if (_d1 < _d2) { RETURN( true ); }
+ RETURN (false );
+ }
+ }
+ RETURN (false );
+ }
}
#endif /* LSBFIRST */
%}.
@@ -3746,22 +3912,22 @@
"/ numbers to be compared ...
[myLen > 0 and:[(digitByteArray basicAt:myLen) == 0]] whileTrue:[
- myLen := myLen - 1
+ myLen := myLen - 1
].
[otherLen > 0 and:[(otherDigitByteArray basicAt:otherLen) == 0]] whileTrue:[
- otherLen := otherLen - 1
+ otherLen := otherLen - 1
].
(myLen < otherLen) ifTrue:[^ true].
(myLen > otherLen) ifTrue:[^ false].
[myLen > 0] whileTrue:[
- d1 := digitByteArray basicAt:myLen.
- d2 := otherDigitByteArray basicAt:myLen.
- d1 == d2 ifFalse:[
- (d1 < d2) ifTrue:[^ true].
- ^ false
- ].
- myLen := myLen - 1
+ d1 := digitByteArray basicAt:myLen.
+ d2 := otherDigitByteArray basicAt:myLen.
+ d1 == d2 ifFalse:[
+ (d1 < d2) ifTrue:[^ true].
+ ^ false
+ ].
+ myLen := myLen - 1
].
^ false
@@ -3804,49 +3970,49 @@
#if defined(__LSBFIRST__)
if (__isByteArray(__INST(digitByteArray))
&& __isLargeInteger(aLargeInteger)) {
- OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
-
- if (__isByteArray(_otherDigitByteArray)) {
- unsigned char *_myDigits = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
- unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
- INT _myLen = __byteArraySize(__INST(digitByteArray));
-
- if (_myLen == __POINTER_SIZE__) {
- INT _otherLen = __byteArraySize(_otherDigitByteArray);
-
- if (_otherLen == __POINTER_SIZE__) {
- unsigned INT _myVal = *((unsigned INT *)_myDigits);
- unsigned INT _otherVal = *((unsigned INT *)_otherDigits);
- RETURN( (_myVal <= _otherVal) ? true : false );
- }
- }
+ OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
+
+ if (__isByteArray(_otherDigitByteArray)) {
+ unsigned char *_myDigits = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
+ unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
+ INT _myLen = __byteArraySize(__INST(digitByteArray));
+
+ if (_myLen == __POINTER_SIZE__) {
+ INT _otherLen = __byteArraySize(_otherDigitByteArray);
+
+ if (_otherLen == __POINTER_SIZE__) {
+ unsigned INT _myVal = *((unsigned INT *)_myDigits);
+ unsigned INT _otherVal = *((unsigned INT *)_otherDigits);
+ RETURN( (_myVal <= _otherVal) ? true : false );
+ }
+ }
# if defined(UINT64) && (__POINTER_SIZE__ != 8)
- if (_myLen == __POINTER_SIZE__) {
- INT _otherLen = __byteArraySize(_otherDigitByteArray);
-
- if (_otherLen <= 8) {
- UINT64 _myVal = (UINT64)(*((UINT *)_myDigits));
- UINT64 _otherVal = *((UINT64 *)_otherDigits);
- RETURN( (_myVal <= _otherVal) ? true : false );
- }
- } else {
- if (_myLen <= 8) {
- INT _otherLen = __byteArraySize(_otherDigitByteArray);
-
- if (_otherLen <= 8) {
- UINT64 _myVal = (*((UINT64 *)_myDigits));
- UINT64 _otherVal = *((UINT64 *)_otherDigits);
- RETURN( (_myVal <= _otherVal) ? true : false );
- }
- if (_otherLen == __POINTER_SIZE__) {
- UINT64 _myVal = (*((UINT64 *)_myDigits));
- UINT64 _otherVal = (UINT64) *((UINT *)_otherDigits);
- RETURN( (_myVal <= _otherVal) ? true : false );
- }
- }
- }
+ if (_myLen == __POINTER_SIZE__) {
+ INT _otherLen = __byteArraySize(_otherDigitByteArray);
+
+ if (_otherLen <= 8) {
+ UINT64 _myVal = (UINT64)(*((UINT *)_myDigits));
+ UINT64 _otherVal = *((UINT64 *)_otherDigits);
+ RETURN( (_myVal <= _otherVal) ? true : false );
+ }
+ } else {
+ if (_myLen <= 8) {
+ INT _otherLen = __byteArraySize(_otherDigitByteArray);
+
+ if (_otherLen <= 8) {
+ UINT64 _myVal = (*((UINT64 *)_myDigits));
+ UINT64 _otherVal = *((UINT64 *)_otherDigits);
+ RETURN( (_myVal <= _otherVal) ? true : false );
+ }
+ if (_otherLen == __POINTER_SIZE__) {
+ UINT64 _myVal = (*((UINT64 *)_myDigits));
+ UINT64 _otherVal = (UINT64) *((UINT *)_otherDigits);
+ RETURN( (_myVal <= _otherVal) ? true : false );
+ }
+ }
+ }
# endif /* UINT64 */
- }
+ }
}
#endif /* LSBFIRST */
%}.
@@ -3861,22 +4027,22 @@
"/ numbers to be compared ...
[(digitByteArray basicAt:myLen) == 0] whileTrue:[
- myLen := myLen - 1
+ myLen := myLen - 1
].
[(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[
- otherLen := otherLen - 1
+ otherLen := otherLen - 1
].
(myLen < otherLen) ifTrue:[^ true].
(myLen > otherLen) ifTrue:[^ false].
[myLen > 0] whileTrue:[
- d1 := digitByteArray basicAt:myLen.
- d2 := otherDigitByteArray basicAt:myLen.
- d1 == d2 ifFalse:[
- (d1 < d2) ifTrue:[^ true].
- ^ false.
- ].
- myLen := myLen - 1
+ d1 := digitByteArray basicAt:myLen.
+ d2 := otherDigitByteArray basicAt:myLen.
+ d1 == d2 ifFalse:[
+ (d1 < d2) ifTrue:[^ true].
+ ^ false.
+ ].
+ myLen := myLen - 1
].
^ true
@@ -3908,9 +4074,9 @@
len2 := otherDigitByteArray size.
len1 > len2 ifTrue:[
- lResult := len1
+ lResult := len1
] ifFalse:[
- lResult := (len1 max: len2) + 1.
+ lResult := (len1 max: len2) + 1.
].
result := self class basicNew numberOfDigits:lResult sign:newSign.
resultDigitByteArray := result digitBytes.
@@ -3923,202 +4089,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.
@@ -4127,40 +4293,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
@@ -4177,34 +4343,34 @@
shift "{ Class: SmallInteger }" |
anInteger == 0 ifTrue:[
- ^ ZeroDivide raiseRequestWith:thisContext
+ ^ ZeroDivide raiseRequestWith:thisContext
].
self = anInteger ifTrue:[
- ^ 0
+ ^ 0
].
shift := self highBit - anInteger highBit.
dividend := self class digitBytes:digitByteArray copy. "/ self simpleDeepCopy sign:1.
shift < 0 ifTrue:[
- ^ dividend compressed.
+ ^ dividend compressed.
].
shift == 0 ifTrue:[
- divisor := LargeInteger digitBytes:(anInteger digitBytes copy). "/ anInteger simpleDeepCopy
+ divisor := LargeInteger digitBytes:(anInteger digitBytes copy). "/ anInteger simpleDeepCopy
] ifFalse:[
- divisor := anInteger bitShift:shift.
+ divisor := anInteger bitShift:shift.
].
shift := shift + 1.
[shift > 0] whileTrue:[
- (dividend absLess:divisor) ifFalse:[
- (dividend absSubtract: divisor) ifFalse:[ "result == 0"
- ^ 0
- ].
- ].
- shift := shift - 1.
- divisor div2.
+ (dividend absLess:divisor) ifFalse:[
+ (dividend absDestructiveSubtract: divisor) ifFalse:[ "result == 0"
+ ^ 0
+ ].
+ ].
+ shift := shift - 1.
+ divisor div2.
].
^ dividend compressed
@@ -4239,9 +4405,9 @@
otherDigitByteArray := aLargeInteger digitBytes.
len2 := otherDigitByteArray size.
lenRslt := len1 + len2.
- UseKarazuba ~~ false ifTrue:[
- lenRslt > 400 ifTrue:[ ^ self absMulKarazuba:aLargeInteger ].
- ].
+ UseKarazuba ~~ false ifTrue:[
+ lenRslt > 400 ifTrue:[ ^ self absMulKarazuba:aLargeInteger ].
+ ].
result := self class basicNew numberOfDigits:lenRslt.
resultDigitByteArray := result digitBytes.
@@ -4251,304 +4417,305 @@
&& __isByteArray(otherDigitByteArray)
&& __isByteArray(resultDigitByteArray)
&& __bothSmallInteger(len1, len2)) {
- unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
- unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
- unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
- unsigned char *_p1, *_pResult0, *_p1Last, *_p2Last, *_pResultLast;
- unsigned char *_pResultLastShort, *_pResultLastInt;
- unsigned INT _v;
- int _len1 = __intVal(len1);
- int _len2 = __intVal(len2);
-
- _p1Last = myBytes + _len1 - 1; /* the last byte */
- _p2Last = otherBytes + _len2 - 1; /* the last byte */
- _pResult0 = resultBytes;
- _pResultLast = resultBytes + _len1 + _len2 - 1; /* the last byte */
-
- /*
- * aaa...aaa f1[0] * f2
- * bbb...bbb f1[1] * f2
- * ccc...ccc f1[2] * f2
- * ...
- * xxx...xxx f1[high] * f2
- *
- * start short-wise
- * bounds: (16rFFFF * 16rFFFF) + 16rFFFF -> FFFF0000
- */
- _p1 = myBytes;
+ unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
+ unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+ unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+ unsigned char *_p1, *_pResult0, *_p1Last, *_p2Last, *_pResultLast;
+ unsigned char *_pResultLastShort, *_pResultLastInt;
+ unsigned INT _v;
+ int _len1 = __intVal(len1);
+ int _len2 = __intVal(len2);
+
+ _p1Last = myBytes + _len1 - 1; /* the last byte */
+ _p2Last = otherBytes + _len2 - 1; /* the last byte */
+ _pResult0 = resultBytes;
+ _pResultLast = resultBytes + _len1 + _len2 - 1; /* the last byte */
+
+ /*
+ * aaa...aaa f1[0] * f2
+ * bbb...bbb f1[1] * f2
+ * ccc...ccc f1[2] * f2
+ * ...
+ * xxx...xxx f1[high] * f2
+ *
+ * start short-wise
+ * bounds: (16rFFFF * 16rFFFF) + 16rFFFF -> FFFF0000
+ */
+ _p1 = myBytes;
#if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8)
- _pResultLastInt = _pResultLast - 3; /* the last int */
-
- /* loop over ints of f1 */
- for (; _p1 <= (_p1Last-3); _p1 += 4, _pResult0 += 4) {
- unsigned char *_pResult, *_p2;
- unsigned INT word1 = ((unsigned int *)_p1)[0];
-
- _pResult = _pResult0;
- _p2 = otherBytes;
-
- /* loop over ints of f2 */
- while (_p2 <= (_p2Last-3)) {
- _v = (word1 * (unsigned INT)(((unsigned int *)_p2)[0])) + ((unsigned INT)((unsigned int *)_pResult)[0]);
- ((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
- _v >>= 32; /* now _v contains the carry*/
- _pResult += 4;
- if (_v) {
- unsigned char *_pResult1;
-
- /* distribute carry - int-wise, then byte-wise */
- for (_pResult1 = _pResult; _v; _pResult1 += 4) {
- if (_pResult1 > _pResultLastInt) break;
- _v += (unsigned INT)(((unsigned int *)_pResult1)[0]);
- ((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
- _v >>= 32;
- }
- for (; _v; _pResult1++) {
- _v += _pResult1[0];
- _pResult1[0] = _v /* & 0xFF */;
- _v >>= 8;
- }
- }
- _p2 += 4;
- }
-
- /* possible odd highByte of f2 */
- while (_p2 <= _p2Last) {
- _v = (word1 * (unsigned INT)((unsigned char *)_p2[0])) + (unsigned INT)((unsigned char *)_pResult[0]);
-
- ((unsigned char *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
- _v >>= 8; /* now _v contains the carry*/
- _pResult++;
- if (_v) {
- unsigned char *_pResult1 = _pResult;
-
- /* distribute carry byte-wise */
- for (; _v; _pResult1++) {
- _v += _pResult1[0];
- _pResult1[0] = _v /* & 0xFF */;
- _v >>= 8;
- }
- }
- _p2++;
- }
- }
+ _pResultLastInt = _pResultLast - 3; /* the last int */
+
+ /* loop over ints of f1 */
+ for (; _p1 <= (_p1Last-3); _p1 += 4, _pResult0 += 4) {
+ unsigned char *_pResult, *_p2;
+ unsigned INT word1 = ((unsigned int *)_p1)[0];
+
+ _pResult = _pResult0;
+ _p2 = otherBytes;
+
+ /* loop over ints of f2 */
+ while (_p2 <= (_p2Last-3)) {
+ _v = (word1 * (unsigned INT)(((unsigned int *)_p2)[0])) + ((unsigned INT)((unsigned int *)_pResult)[0]);
+ ((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
+ _v >>= 32; /* now _v contains the carry*/
+ _pResult += 4;
+ if (_v) {
+ unsigned char *_pResult1;
+
+ /* distribute carry - int-wise, then byte-wise */
+ for (_pResult1 = _pResult; _v; _pResult1 += 4) {
+ if (_pResult1 > _pResultLastInt) break;
+ _v += (unsigned INT)(((unsigned int *)_pResult1)[0]);
+ ((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
+ _v >>= 32;
+ }
+ for (; _v; _pResult1++) {
+ _v += _pResult1[0];
+ _pResult1[0] = _v /* & 0xFF */;
+ _v >>= 8;
+ }
+ }
+ _p2 += 4;
+ }
+
+ /* possible odd highByte of f2 */
+ while (_p2 <= _p2Last) {
+ _v = (word1 * (unsigned INT)(((unsigned char *)_p2)[0]))
+ + (unsigned INT)(((unsigned char *)_pResult)[0]);
+
+ ((unsigned char *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
+ _v >>= 8; /* now _v contains the carry*/
+ _pResult++;
+ if (_v) {
+ unsigned char *_pResult1 = _pResult;
+
+ /* distribute carry byte-wise */
+ for (; _v; _pResult1++) {
+ _v += _pResult1[0];
+ _pResult1[0] = _v /* & 0xFF */;
+ _v >>= 8;
+ }
+ }
+ _p2++;
+ }
+ }
#endif /* 64bit */
- /* possible odd high short of f1 (or shortLoop, if not 64bit) */
- _pResultLastShort = _pResultLast - 1; /* the last short */
-
- for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
- unsigned char *_pResult, *_p2;
- unsigned int short1 = ((unsigned short *)_p1)[0];
+ /* possible odd high short of f1 (or shortLoop, if not 64bit) */
+ _pResultLastShort = _pResultLast - 1; /* the last short */
+
+ for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
+ unsigned char *_pResult, *_p2;
+ unsigned int short1 = ((unsigned short *)_p1)[0];
#if !defined(__LSBFIRST__)
- short1 = ((short1 >> 8) & 0xFF) | ((short1 & 0xFF) << 8);
+ short1 = ((short1 >> 8) & 0xFF) | ((short1 & 0xFF) << 8);
#endif
- _pResult = _pResult0;
- _p2 = otherBytes;
-
- /* loop over shorts of f2 */
- while (_p2 < _p2Last) {
+ _pResult = _pResult0;
+ _p2 = otherBytes;
+
+ /* loop over shorts of f2 */
+ while (_p2 < _p2Last) {
#if !defined(__LSBFIRST__)
- unsigned int _short2;
- unsigned int _short3;
-
- _short2 = ((unsigned short *)_p2)[0];
- _short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
- _short3 = ((unsigned short *)_pResult)[0];
- _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
- _v = (short1 * _short2) + _short3;
- _pResult[0] = _v;
- _pResult[1] = _v >> 8;
+ unsigned int _short2;
+ unsigned int _short3;
+
+ _short2 = ((unsigned short *)_p2)[0];
+ _short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
+ _short3 = ((unsigned short *)_pResult)[0];
+ _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
+ _v = (short1 * _short2) + _short3;
+ _pResult[0] = _v;
+ _pResult[1] = _v >> 8;
#else /* __LSBFIRST__ */
- _v = (short1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
- ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+ _v = (short1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
+ ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
#endif
- _v >>= 16; /* now _v contains the carry*/
- _pResult += 2;
- if (_v) {
- unsigned char *_pResult1;
-
- /* distribute carry - short-wise, then byte-wise */
- _pResult1 = _pResult;
+ _v >>= 16; /* now _v contains the carry*/
+ _pResult += 2;
+ if (_v) {
+ unsigned char *_pResult1;
+
+ /* distribute carry - short-wise, then byte-wise */
+ _pResult1 = _pResult;
#if defined(__LSBFIRST__)
- for (; _v; _pResult1 += 2) {
- if (_pResult1 > _pResultLastShort) break;
- _v += ((unsigned short *)_pResult1)[0];
- ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
- _v >>= 16;
- }
+ for (; _v; _pResult1 += 2) {
+ if (_pResult1 > _pResultLastShort) break;
+ _v += ((unsigned short *)_pResult1)[0];
+ ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
+ _v >>= 16;
+ }
#endif
- for (; _v; _pResult1++) {
- _v += _pResult1[0];
- _pResult1[0] = _v /* & 0xFF */;
- _v >>= 8;
- }
- }
- _p2 += 2;
- }
-
- /* possible odd highByte of f2 */
- if (_p2 <= _p2Last) {
+ for (; _v; _pResult1++) {
+ _v += _pResult1[0];
+ _pResult1[0] = _v /* & 0xFF */;
+ _v >>= 8;
+ }
+ }
+ _p2 += 2;
+ }
+
+ /* possible odd highByte of f2 */
+ if (_p2 <= _p2Last) {
#if !defined(__LSBFIRST__)
- unsigned int _short3;
-
- _short3 = ((unsigned short *)_pResult)[0];
- _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
- _v = (short1 * _p2[0]) + _short3;
- _pResult[0] = _v;
- _pResult[1] = _v >> 8;
+ unsigned int _short3;
+
+ _short3 = ((unsigned short *)_pResult)[0];
+ _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
+ _v = (short1 * _p2[0]) + _short3;
+ _pResult[0] = _v;
+ _pResult[1] = _v >> 8;
#else /* __LSBFIRST__ */
- _v = (short1 * _p2[0]) + ((unsigned short *)_pResult)[0];
- ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+ _v = (short1 * _p2[0]) + ((unsigned short *)_pResult)[0];
+ ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
#endif
- _v >>= 16; /* now _v contains the carry*/
- _pResult += 2;
- if (_v) {
- unsigned char *_pResult1;
-
- /* distribute carry - short-wise, then byte-wise */
- _pResult1 = _pResult;
+ _v >>= 16; /* now _v contains the carry*/
+ _pResult += 2;
+ if (_v) {
+ unsigned char *_pResult1;
+
+ /* distribute carry - short-wise, then byte-wise */
+ _pResult1 = _pResult;
#if defined(__LSBFIRST__)
- for (; _v; _pResult1 += 2) {
- if (_pResult1 > _pResultLastShort) break;
- _v += ((unsigned short *)_pResult1)[0];
- ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
- _v >>= 16;
- }
+ for (; _v; _pResult1 += 2) {
+ if (_pResult1 > _pResultLastShort) break;
+ _v += ((unsigned short *)_pResult1)[0];
+ ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
+ _v >>= 16;
+ }
#endif
- for (; _v; _pResult1++) {
- _v += _pResult1[0];
- _pResult1[0] = _v /* & 0xFF */;
- _v >>= 8;
- }
- }
- _p2++;
- }
- }
-
- /* possible odd highByte of f1 (or byteLoop, if above is ever disabled) */
- for (; _p1 <= _p1Last; _p1++, _pResult0++) {
- unsigned char *_pResult, *_p2;
- unsigned int byte1 = _p1[0];
-
- _pResult = _pResult0;
- _p2 = otherBytes;
-
- /* loop over shorts of f2 */
- while (_p2 < _p2Last) {
+ for (; _v; _pResult1++) {
+ _v += _pResult1[0];
+ _pResult1[0] = _v /* & 0xFF */;
+ _v >>= 8;
+ }
+ }
+ _p2++;
+ }
+ }
+
+ /* possible odd highByte of f1 (or byteLoop, if above is ever disabled) */
+ for (; _p1 <= _p1Last; _p1++, _pResult0++) {
+ unsigned char *_pResult, *_p2;
+ unsigned int byte1 = _p1[0];
+
+ _pResult = _pResult0;
+ _p2 = otherBytes;
+
+ /* loop over shorts of f2 */
+ while (_p2 < _p2Last) {
#if !defined(__LSBFIRST__)
- unsigned int _short2;
- unsigned int _short3;
-
- _short2 = ((unsigned short *)_p2)[0];
- _short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
- _short3 = ((unsigned short *)_pResult)[0];
- _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
- _v = (byte1 * _short2) + _short3;
- _pResult[0] = _v;
- _pResult[1] = _v >> 8;
+ unsigned int _short2;
+ unsigned int _short3;
+
+ _short2 = ((unsigned short *)_p2)[0];
+ _short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
+ _short3 = ((unsigned short *)_pResult)[0];
+ _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
+ _v = (byte1 * _short2) + _short3;
+ _pResult[0] = _v;
+ _pResult[1] = _v >> 8;
#else /* __LSBFIRST__ */
- _v = (byte1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
- ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+ _v = (byte1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
+ ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
#endif
- _v >>= 16; /* now _v contains the carry*/
- _pResult += 2;
- if (_v) {
- unsigned char *_pResult1;
-
- /* distribute carry - short-wise, then byte-wise */
- _pResult1 = _pResult;
+ _v >>= 16; /* now _v contains the carry*/
+ _pResult += 2;
+ if (_v) {
+ unsigned char *_pResult1;
+
+ /* distribute carry - short-wise, then byte-wise */
+ _pResult1 = _pResult;
#if defined(__LSBFIRST__)
- for (_pResult1 = _pResult; _v; _pResult1 += 2) {
- if (_pResult1 > _pResultLastShort) break;
- _v += ((unsigned short *)_pResult1)[0];
- ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
- _v >>= 16;
- }
+ for (_pResult1 = _pResult; _v; _pResult1 += 2) {
+ if (_pResult1 > _pResultLastShort) break;
+ _v += ((unsigned short *)_pResult1)[0];
+ ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
+ _v >>= 16;
+ }
#endif /* __LSBFIRST__ */
- for (; _v; _pResult1++) {
- _v += _pResult1[0];
- _pResult1[0] = _v /* & 0xFF */;
- _v >>= 8;
- }
- }
- _p2 += 2;
- }
-
- /* possible odd highByte of f2 (or byteLoop, if not __LSBFIRST__) */
- while (_p2 <= _p2Last) {
- _v = (byte1 * _p2[0]) + _pResult[0];
- _pResult[0] = _v /* & 0xFF */;
- _v >>= 8; /* now _v contains the carry*/
- _pResult++;
- if (_v) {
- unsigned char *_pResult1;
-
- /* distribute carry */
- for (_pResult1 = _pResult; _v; _pResult1++) {
- _v += _pResult1[0];
- _pResult1[0] = _v /* & 0xFF */;
- _v >>= 8;
- }
- }
- _p2++;
- }
- }
- ok = true;
+ for (; _v; _pResult1++) {
+ _v += _pResult1[0];
+ _pResult1[0] = _v /* & 0xFF */;
+ _v >>= 8;
+ }
+ }
+ _p2 += 2;
+ }
+
+ /* possible odd highByte of f2 (or byteLoop, if not __LSBFIRST__) */
+ while (_p2 <= _p2Last) {
+ _v = (byte1 * _p2[0]) + _pResult[0];
+ _pResult[0] = _v /* & 0xFF */;
+ _v >>= 8; /* now _v contains the carry*/
+ _pResult++;
+ if (_v) {
+ unsigned char *_pResult1;
+
+ /* distribute carry */
+ for (_pResult1 = _pResult; _v; _pResult1++) {
+ _v += _pResult1[0];
+ _pResult1[0] = _v /* & 0xFF */;
+ _v >>= 8;
+ }
+ }
+ _p2++;
+ }
+ }
+ ok = true;
}
%}.
ok ifFalse:[
- 1 to:len1 do:[:index1 |
- 1 to:len2 do:[:index2 |
- dstIndex := index1 + index2 - 1.
- prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
- prod := prod + (resultDigitByteArray basicAt:dstIndex).
- resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
- carry := prod bitShift:-8.
- carry ~~ 0 ifTrue:[
- idx := dstIndex + 1.
- [carry ~~ 0] whileTrue:[
- v := (resultDigitByteArray basicAt:idx) + carry.
- resultDigitByteArray basicAt:idx put:(v bitAnd:255).
- carry := v bitShift:-8.
- idx := idx + 1
- ]
- ]
- ]
- ].
+ 1 to:len1 do:[:index1 |
+ 1 to:len2 do:[:index2 |
+ dstIndex := index1 + index2 - 1.
+ prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
+ prod := prod + (resultDigitByteArray basicAt:dstIndex).
+ resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
+ carry := prod bitShift:-8.
+ carry ~~ 0 ifTrue:[
+ idx := dstIndex + 1.
+ [carry ~~ 0] whileTrue:[
+ v := (resultDigitByteArray basicAt:idx) + carry.
+ resultDigitByteArray basicAt:idx put:(v bitAnd:255).
+ carry := v bitShift:-8.
+ idx := idx + 1
+ ]
+ ]
+ ]
+ ].
].
^ result compressed
!
absMulKarazuba:aLargeInteger
"return a LargeInteger representing abs(self) * abs(theArgument) using the karazuba algorithm.
- a = (2^n * p) + q
- b = (2^n * r) + s
- a * b = ((2^n * p) + q) * ((2^n * r) + s)
- = 2^(n+n)*p*r + 2^n*p*s + 2^n*q*r + q*s
- = 2^(n+n)*p*r + (p*r + q*s - (q-p)*(s-r))*2^n + q*s
-
- this is faster for sufficient large n1,n2
- because regular multiplication is O(n1*n2) and karazuma multiplies much smaller numbers
- (half number of bits) but does more multiplations (on smaller numbers) and req's more
- additions and subtractions (on smaller numbers).
- The break-even for when to use regular multiplication has been determined heuristically
- and is somewhere around 1600 bits (digitLength of 200).
- (see test in absMul:)
-
- To disable karazuba, set UseKarazuba to false.
+ a = (2^n * p) + q
+ b = (2^n * r) + s
+ a * b = ((2^n * p) + q) * ((2^n * r) + s)
+ = 2^(n+n)*p*r + 2^n*p*s + 2^n*q*r + q*s
+ = 2^(n+n)*p*r + (p*r + q*s - (q-p)*(s-r))*2^n + q*s
+
+ this is faster for sufficient large n1,n2
+ because regular multiplication is O(n1*n2) and karazuma multiplies much smaller numbers
+ (half number of bits) but does more multiplations (on smaller numbers) and req's more
+ additions and subtractions (on smaller numbers).
+ The break-even for when to use regular multiplication has been determined heuristically
+ and is somewhere around 1600 bits (digitLength of 200).
+ (see test in absMul:)
+
+ To disable karazuba, set UseKarazuba to false.
"
"/ compute half-sized pi and qi...
|l1 l2 n nh p q r s pr qs q_p s_r q_ps_r pr_raisedTo_n mdl_raisedTo_nh|
-
+
l1 := self digitLength.
l2 := aLargeInteger digitLength.
-
+
n := l1 max:l2.
-
+
nh := (n / 2) ceiling. n := nh * 2.
p := LargeInteger digitBytes:(digitByteArray copyFrom:nh+1) sign:1. "/ high bits of nr1
q := LargeInteger digitBytes:(digitByteArray copyToMax:nh) sign:1. "/ low bits of nr1
@@ -4559,26 +4726,26 @@
q := q compressed.
r := r compressed.
s := s compressed.
-
+
pr := p * r.
qs := q * s.
q_p := q - p.
s_r := s - r.
q_ps_r := q_p * s_r.
-
+
pr_raisedTo_n := (pr bitShift:(n*8)).
mdl_raisedTo_nh := ((pr + qs - q_ps_r) bitShift:(nh*8)).
^ pr_raisedTo_n + mdl_raisedTo_nh + qs
"
#(100 500 1000 2500 5000 10000 25000 50000 100000 250000 500000 1000000) do:[:exp |
- |nr r1 r2|
- nr := (3 raisedTo:exp) asInteger.
- Transcript show:exp; show:' nbytes: '; showCR:nr digitLength;
- show:' normal: '; show:(Time microsecondsToRun:[ UseKarazuba := false. r1 := nr * nr ]); showCR:'us';
- show:' karazuba: '; show:(Time microsecondsToRun:[ UseKarazuba := true. r2 := nr absMulKarazuba: nr]); showCR:'us'.
- self assert:(r1 = r2).
- ]
+ |nr r1 r2|
+ nr := (3 raisedTo:exp) asInteger.
+ Transcript show:exp; show:' nbytes: '; showCR:nr digitLength;
+ show:' normal: '; show:(Time microsecondsToRun:[ UseKarazuba := false. r1 := nr * nr ]); showCR:'us';
+ show:' karazuba: '; show:(Time microsecondsToRun:[ UseKarazuba := true. r2 := nr absMulKarazuba: nr]); showCR:'us'.
+ self assert:(r1 = r2).
+ ]
"
!
@@ -4604,494 +4771,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(__LSBFIRST__)
- 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__) && defined(__alpha__)
+# if (__POINTER_SIZE__ == 8) && defined(__GNUC__) && defined(__alpha__)
# 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 / notdef */
# endif /* 64bit alpha */
# if (__POINTER_SIZE__ == 8)
# if 0 /* not faster */
- {
- 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 setSign: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
@@ -5099,221 +5266,6 @@
"Modified: 11.8.1997 / 03:23:37 / cg"
!
-absSubtract:aLargeInteger
- "private helper for division:
- destructively subtract aLargeInteger from myself
- AND return true, if the result is non-zero, false otherwise.
- (i.e. this method has both a return value and a side-effect
- on the receiver)
- Only allowed for positive receiver and argument
- The receiver must be >= the argument.
- The receiver must be a temporary scratch-number"
-
- |otherDigitByteArray
- len1 "{ Class: SmallInteger }"
- len2 "{ Class: SmallInteger }"
- index "{ Class: SmallInteger }"
- borrow "{ Class: SmallInteger }"
- diff "{ Class: SmallInteger }"
- notZero
- |
-
- notZero := false.
- len1 := digitByteArray size.
- otherDigitByteArray := aLargeInteger digitBytes.
- len2 := otherDigitByteArray size.
- len2 > len1 ifTrue:[
- [(otherDigitByteArray at:len2) == 0] whileTrue:[
- len2 := len2 - 1
- ].
- len2 > len1 ifTrue:[
- self error:'operation failed' "/ may not be called that way
- ].
- ].
- "/ knowing that len2 is <= len1
-%{
-
- OBJ _digitByteArray = __INST(digitByteArray);
-
- if (__isByteArray(_digitByteArray)
- && __isByteArray(otherDigitByteArray)) {
- int _len1 = __intVal(len1),
- _len2 = __intVal(len2);
- unsigned char *_myDigits, *_otherDigits;
- int _index = 1, _borrow = 0;
- INT _diff;
- int anyBitNonZero = 0;
-
- _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
- _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
-
-#if defined(__LSBFIRST__)
-# if __POINTER_SIZE__ == 8
- {
- int _len2Q;
- /*
- * subtract int-wise
- */
- _len2Q = _len2-2;
- while (_index < _len2Q) {
- /* do not combine the expression below (may lead to unsigned result on some machines */
- _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 *)(_myDigits+_index-1))[0] = _diff;
- anyBitNonZero |= (_diff & 0xFFFFFFFFL);
- _index += 4;
- }
- }
-# endif
-
- /*
- * subtract short-wise
- */
- while (_index < _len2) {
- /* do not combine the expression below (may lead to unsigned result on some machines */
- _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 *)(_myDigits+_index-1))[0] = _diff;
- anyBitNonZero |= (_diff & 0xFFFF);
- _index += 2;
- }
-
- if (_index <= _len2) {
- /*
- * cannot continue with shorts - there is an odd number of
- * bytes in the minuent
- */
- } else {
- while (_index < _len1) {
- /* do not combine the expression below (may lead to unsigned result on some machines */
- _diff = ((unsigned short *)(_myDigits+_index-1))[0];
- _diff -= _borrow;
- if (_diff >= 0) {
- /* _borrow = 0; */
- ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
- anyBitNonZero |= (_diff & 0xFFFF);
- _index += 2;
- while (_index < _len1) {
- anyBitNonZero |= ((unsigned short *)(_myDigits+_index-1))[0];
- if (anyBitNonZero) {
- RETURN (true);
- }
- _index += 2;
- }
- /* last odd index */
- if (_index <= _len1) {
- anyBitNonZero |= _myDigits[_index - 1];;
- if (anyBitNonZero) {
- RETURN (true);
- }
- _index++;
- }
- RETURN (anyBitNonZero ? true : false);
- }
- _borrow = 1;
- /* _diff += 0x10000; */
-
- ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
- anyBitNonZero |= (_diff & 0xFFFF);
- _index += 2;
- }
- }
-#endif
- /*
- * subtract byte-wise
- */
- while (_index <= _len2) {
- /* do not combine the expression below (may lead to unsigned result on some machines */
- _diff = _myDigits[_index - 1];
- _diff -= _otherDigits[_index - 1];
- _diff -= _borrow;
- if (_diff >= 0) {
- _borrow = 0;
- } else {
- _borrow = 1;
- /* _diff += 0x100; */
- }
- _myDigits[_index - 1] = _diff;
- anyBitNonZero |= (_diff & 0xFF);
- _index++;
- }
-
- while (_index <= _len1) {
- /* do not combine the expression below (may lead to unsigned result on some machines */
- _diff = _myDigits[_index - 1];
- _diff -= _borrow;
- if (_diff >= 0) {
- /* _borrow = 0; */
- _myDigits[_index - 1] = _diff;
- anyBitNonZero |= (_diff & 0xFF);
- _index++;
- while (_index <= _len1) {
- anyBitNonZero |= _myDigits[_index - 1];
- if (anyBitNonZero) {
- RETURN (true);
- }
- _index++;
- }
- break;
- }
- _borrow = 1;
- /* _diff += 0x100; */
-
- _myDigits[_index - 1] = _diff;
- anyBitNonZero |= (_diff & 0xFF);
- _index++;
- }
- RETURN (anyBitNonZero ? true : false);
- }
-%}.
-
- index := 1.
- borrow := 0.
-
- [index <= len1] whileTrue:[
- diff := borrow.
- diff := diff + (digitByteArray basicAt:index).
- index <= len2 ifTrue:[
- diff := diff - (otherDigitByteArray basicAt:index).
- ].
-
- "/ workaround for
- "/ gcc code generator bug
-
- (diff >= 0) ifTrue:[
- borrow := 0
- ] ifFalse:[
- borrow := -1.
- diff := diff + 16r100
- ].
- diff ~~ 0 ifTrue:[
- notZero := true
- ].
- digitByteArray basicAt:index put:diff.
- index := index + 1
- ].
-
- ^ notZero
-
- "Created: / 5.11.1996 / 16:23:47 / cg"
- "Modified: / 5.11.1996 / 18:56:50 / cg"
- "Modified: / 27.4.1999 / 18:08:23 / stefan"
-!
-
div2
"private helper for division:
destructively divide the receiver by 2.
@@ -5325,103 +5277,103 @@
OBJ __digits = __INST(digitByteArray);
if (__isByteArray(__digits)) {
- int __nBytes = __byteArraySize(__digits);
- unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
- unsigned INT __this, __next;
- int __idx;
-
- if (__nBytes == 1) {
- __bp[0] >>= 1;
- RETURN (self);
- }
-
- __idx = 1;
+ int __nBytes = __byteArraySize(__digits);
+ unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
+ unsigned INT __this, __next;
+ int __idx;
+
+ if (__nBytes == 1) {
+ __bp[0] >>= 1;
+ RETURN (self);
+ }
+
+ __idx = 1;
#if defined(__LSBFIRST__)
# if (__POINTER_SIZE__ == 8)
- if (sizeof(unsigned INT) == 8) {
- int __endIndex = __nBytes - 8;
-
- if (__idx < __endIndex) {
- __this = ((unsigned INT *)__bp)[0];
-
- while (__idx < __endIndex) {
- __next = ((unsigned INT *)__bp)[1];
- __this = (__this >> 1) /* & 0x7FFFFFFFFFFFFFF */;
- __this |= __next << 63;
- ((unsigned INT *)__bp)[0] = __this;
- __this = __next;
- __bp += 8;
- __idx += 8;
- }
- }
-
- if (__idx < (__nBytes - 4)) {
- __this = ((unsigned int *)__bp)[0];
-
- __next = ((unsigned int *)__bp)[1];
- __this = (__this >> 1) /* & 0x7FFFFFF */;
- __this |= __next << 31;
- ((unsigned int *)__bp)[0] = __this;
- __this = __next;
- __bp += 4;
- __idx += 4;
- }
- if (__idx < (__nBytes - 2)) {
- __this = ((unsigned short *)__bp)[0];
-
- __next = ((unsigned short *)__bp)[1];
- __this = (__this >> 1) /* & 0x7FFFFFF */;
- __this |= __next << 15;
- ((unsigned short *)__bp)[0] = __this;
- __this = __next;
- __bp += 2;
- __idx += 2;
- }
- }
+ if (sizeof(unsigned INT) == 8) {
+ int __endIndex = __nBytes - 8;
+
+ if (__idx < __endIndex) {
+ __this = ((unsigned INT *)__bp)[0];
+
+ while (__idx < __endIndex) {
+ __next = ((unsigned INT *)__bp)[1];
+ __this = (__this >> 1) /* & 0x7FFFFFFFFFFFFFF */;
+ __this |= __next << 63;
+ ((unsigned INT *)__bp)[0] = __this;
+ __this = __next;
+ __bp += 8;
+ __idx += 8;
+ }
+ }
+
+ if (__idx < (__nBytes - 4)) {
+ __this = ((unsigned int *)__bp)[0];
+
+ __next = ((unsigned int *)__bp)[1];
+ __this = (__this >> 1) /* & 0x7FFFFFF */;
+ __this |= __next << 31;
+ ((unsigned int *)__bp)[0] = __this;
+ __this = __next;
+ __bp += 4;
+ __idx += 4;
+ }
+ if (__idx < (__nBytes - 2)) {
+ __this = ((unsigned short *)__bp)[0];
+
+ __next = ((unsigned short *)__bp)[1];
+ __this = (__this >> 1) /* & 0x7FFFFFF */;
+ __this |= __next << 15;
+ ((unsigned short *)__bp)[0] = __this;
+ __this = __next;
+ __bp += 2;
+ __idx += 2;
+ }
+ }
# else
- if (sizeof(unsigned int) == 4) {
- int __endIndex = __nBytes - 4;
-
- if (__idx < __endIndex) {
- __this = ((unsigned int *)__bp)[0];
-
- while (__idx < __endIndex) {
- __next = ((unsigned int *)__bp)[1];
- __this = (__this >> 1) /* & 0x7FFFFFF */;
- __this |= __next << 31;
- ((unsigned int *)__bp)[0] = __this;
- __this = __next;
- __bp += 4;
- __idx += 4;
- }
- }
- }
+ if (sizeof(unsigned int) == 4) {
+ int __endIndex = __nBytes - 4;
+
+ if (__idx < __endIndex) {
+ __this = ((unsigned int *)__bp)[0];
+
+ while (__idx < __endIndex) {
+ __next = ((unsigned int *)__bp)[1];
+ __this = (__this >> 1) /* & 0x7FFFFFF */;
+ __this |= __next << 31;
+ ((unsigned int *)__bp)[0] = __this;
+ __this = __next;
+ __bp += 4;
+ __idx += 4;
+ }
+ }
+ }
# endif
#endif
- __this = __bp[0];
- while (__idx < __nBytes) {
- __next = __bp[1];
- __this >>= 1;
- __this |= __next << 7;
- __bp[0] = __this;
- __this = __next;
- __bp++;
- __idx++;
- }
- __bp[0] = __this >> 1;
- RETURN (self);
+ __this = __bp[0];
+ while (__idx < __nBytes) {
+ __next = __bp[1];
+ __this >>= 1;
+ __this |= __next << 7;
+ __bp[0] = __this;
+ __this = __next;
+ __bp++;
+ __idx++;
+ }
+ __bp[0] = __this >> 1;
+ RETURN (self);
}
%}.
prevBit := 0.
digitByteArray size to:1 by:-1 do:[:idx |
- |thisByte|
-
- thisByte := digitByteArray at:idx.
- digitByteArray at:idx put:((thisByte bitShift:-1) bitOr:prevBit).
- prevBit := (thisByte bitAnd:1) bitShift:7.
+ |thisByte|
+
+ thisByte := digitByteArray at:idx.
+ digitByteArray at:idx put:((thisByte bitShift:-1) bitOr:prevBit).
+ prevBit := (thisByte bitAnd:1) bitShift:7.
].
"
@@ -5445,81 +5397,81 @@
b := digitByteArray at:nBytes.
(b bitAnd:16r80) ~~ 0 ifTrue:[
- "/ need another byte
- nBytes := nBytes + 1.
- t := ByteArray uninitializedNew:nBytes.
- t replaceFrom:1 to:nBytes-1 with:digitByteArray startingAt:1.
- t at:nBytes put:0.
- digitByteArray := t.
+ "/ need another byte
+ nBytes := nBytes + 1.
+ t := ByteArray uninitializedNew:nBytes.
+ t replaceFrom:1 to:nBytes-1 with:digitByteArray startingAt:1.
+ t at:nBytes put:0.
+ digitByteArray := t.
].
%{
OBJ __digits = __INST(digitByteArray);
if (__isByteArray(__digits)) {
- int __nBytes = __intVal(nBytes);
- unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
- unsigned INT __carry = 0, __newCarry;
+ int __nBytes = __intVal(nBytes);
+ unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
+ unsigned INT __carry = 0, __newCarry;
#if defined(__LSBFIRST__)
# if (__POINTER_SIZE__ == 8)
- if (sizeof(unsigned INT) == 8) {
- while (__nBytes >= 8) {
- unsigned INT __this;
-
- __this = ((unsigned INT *)__bp)[0];
- __newCarry = (__this >> 63) /* & 1 */;
- ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
- __carry = __newCarry;
- __bp += 8;
- __nBytes -= 8;
- }
- }
+ if (sizeof(unsigned INT) == 8) {
+ while (__nBytes >= 8) {
+ unsigned INT __this;
+
+ __this = ((unsigned INT *)__bp)[0];
+ __newCarry = (__this >> 63) /* & 1 */;
+ ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp += 8;
+ __nBytes -= 8;
+ }
+ }
# endif
- if (sizeof(unsigned int) == 4) {
- while (__nBytes >= 4) {
- unsigned int __this;
-
- __this = ((unsigned int *)__bp)[0];
- __newCarry = (__this >> 31) /* & 1 */;
- ((unsigned int *)__bp)[0] = (__this << 1) | __carry;
- __carry = __newCarry;
- __bp += 4;
- __nBytes -= 4;
- }
- }
- if (__nBytes >= 2) {
- unsigned short __this;
-
- __this = ((unsigned short *)__bp)[0];
- __newCarry = (__this >> 15) /* & 1 */;
- ((unsigned short *)__bp)[0] = (__this << 1) | __carry;
- __carry = __newCarry;
- __bp += 2;
- __nBytes -= 2;
- }
+ if (sizeof(unsigned int) == 4) {
+ while (__nBytes >= 4) {
+ unsigned int __this;
+
+ __this = ((unsigned int *)__bp)[0];
+ __newCarry = (__this >> 31) /* & 1 */;
+ ((unsigned int *)__bp)[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp += 4;
+ __nBytes -= 4;
+ }
+ }
+ if (__nBytes >= 2) {
+ unsigned short __this;
+
+ __this = ((unsigned short *)__bp)[0];
+ __newCarry = (__this >> 15) /* & 1 */;
+ ((unsigned short *)__bp)[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp += 2;
+ __nBytes -= 2;
+ }
#endif /* LSBFIRST */
- while (__nBytes) {
- unsigned char __this;
-
- __this = __bp[0];
- __newCarry = (__this >> 7) /* & 1 */;
- __bp[0] = (__this << 1) | __carry;
- __carry = __newCarry;
- __bp++;
- __nBytes--;
- }
- RETURN (self);
+ while (__nBytes) {
+ unsigned char __this;
+
+ __this = __bp[0];
+ __newCarry = (__this >> 7) /* & 1 */;
+ __bp[0] = (__this << 1) | __carry;
+ __carry = __newCarry;
+ __bp++;
+ __nBytes--;
+ }
+ RETURN (self);
}
%}.
prevBit := 0.
1 to:digitByteArray size do:[:idx |
- |thisByte|
-
- thisByte := digitByteArray at:idx.
- digitByteArray at:idx put:(((thisByte bitShift:1) bitAnd:16rFF) bitOr:prevBit).
- prevBit := (thisByte bitShift:-7) bitAnd:1.
+ |thisByte|
+
+ thisByte := digitByteArray at:idx.
+ digitByteArray at:idx put:(((thisByte bitShift:1) bitAnd:16rFF) bitOr:prevBit).
+ prevBit := (thisByte bitShift:-7) bitAnd:1.
].
"
@@ -5572,9 +5524,25 @@
!
setSign:aNumber
- "destructively change the sign of the receiver"
-
- sign := aNumber
+ "destructively change the sign of the receiver.
+ Return the compressed integer (smallinteger if possible)"
+
+ sign := aNumber.
+%{
+ if (aNumber == __MKSMALLINT(-1)) {
+ if (__byteArraySize(__INST(digitByteArray)) == sizeof(INT)) {
+ if ( ((INT *)(__byteArrayVal(__INST(digitByteArray))))[0] == -_MIN_INT) {
+ RETURN(__MKSMALLINT(_MIN_INT));
+ }
+ }
+ }
+%}.
+
+ "
+ (LargeInteger digitBytes:#[0 0 0 64]) setSign:-1
+ "
+
+ "Modified (comment): / 26-02-2016 / 22:40:27 / cg"
!
sign:aNumber
@@ -5589,7 +5557,7 @@
nextPowerOf2
"return the power of 2 at or above the receiver.
Notice, that for a powerOf2, the receiver is returned.
- Also notice, that (because it is used for padding),
+ Also notice, that (because it is used for padding),
0 is returned for zero."
|newBytes nBytes hi|
@@ -5598,25 +5566,25 @@
nBytes := digitByteArray size.
hi := digitByteArray at:nBytes.
self assert:(hi ~~ 0).
-
+
newBytes := ByteArray new:(nBytes) withAll:16rFF.
(hi isPowerOf:2) ifTrue:[
- newBytes at:nBytes put:((hi bitShift:1)- 1).
- ] ifFalse:[
- newBytes at:nBytes put:(hi nextPowerOf2 - 1).
- ].
+ newBytes at:nBytes put:((hi bitShift:1)- 1).
+ ] ifFalse:[
+ newBytes at:nBytes put:(hi nextPowerOf2 - 1).
+ ].
^ (LargeInteger digitBytes:newBytes) + 1
"
- 100 factorial nextPowerOf2 isPowerOf:2
+ 100 factorial nextPowerOf2 isPowerOf:2
1000 factorial nextPowerOf2 isPowerOf:2
Time millisecondsToRun:[
- |v|
- v := 1000 factorial.
- 1000 timesRepeat:[
- v nextPowerOf2
- ]
- ]
+ |v|
+ v := 1000 factorial.
+ 1000 timesRepeat:[
+ v nextPowerOf2
+ ]
+ ]
"
! !
@@ -5630,13 +5598,13 @@
return context._RETURN( ((STLargeInteger)self).isEven() ? STObject.True : STObject.False);
#else
OBJ digits = __INST(digitByteArray);
-
+
if (__isByteArray(digits)){
- if (__byteArraySize(digits) > 0) {
- unsigned char b = __ByteArrayInstPtr(digits)->ba_element[0];
- RETURN( (b & 1) ? false : true );
- }
- }
+ if (__byteArraySize(digits) > 0) {
+ unsigned char b = __ByteArrayInstPtr(digits)->ba_element[0];
+ RETURN( (b & 1) ? false : true );
+ }
+ }
#endif
%}.
^ (digitByteArray at:1) even
@@ -5670,11 +5638,11 @@
OBJ digits = __INST(digitByteArray);
if (__isByteArray(digits)){
- if (__byteArraySize(digits) > 0) {
- unsigned char b = __ByteArrayInstPtr(digits)->ba_element[0];
- RETURN( (b & 1) ? true : false );
- }
- }
+ if (__byteArraySize(digits) > 0) {
+ unsigned char b = __ByteArrayInstPtr(digits)->ba_element[0];
+ RETURN( (b & 1) ? true : false );
+ }
+ }
#endif
%}.
^ (digitByteArray at:1) odd
@@ -5724,4 +5692,3 @@
version_CVS
^ '$Header$'
! !
-