--- a/LargeInteger.st Tue May 21 21:58:09 2013 +0100
+++ b/LargeInteger.st Fri May 24 18:52:05 2013 +0100
@@ -290,8 +290,6 @@
"Modified: / 8.5.1998 / 21:40:41 / cg"
! !
-
-
!LargeInteger class methodsFor:'queries'!
isBuiltInClass
@@ -456,10 +454,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 ..."
@@ -473,7 +471,7 @@
The result is truncated toward negative infinity and negative,
if the operands signs differ.
The following is always true:
- (receiver // aNumber) * aNumber + (receiver \\ aNUmber) = receiver
+ (receiver // aNumber) * aNumber + (receiver \\ aNUmber) = receiver
"
|cls divMod quo abs "{ Class: SmallInteger }" n|
@@ -486,38 +484,38 @@
Use a special method for this case ...
"
(cls == SmallInteger) ifTrue:[
- abs := aNumber.
- abs := abs abs.
- (abs between:1 and:16r00ffffff) ifTrue:[
- divMod := self absFastDivMod:abs.
- ] ifFalse:[
- n := abs asLargeInteger.
- ].
+ abs := aNumber.
+ abs := abs abs.
+ (abs between:1 and:16r00ffffff) ifTrue:[
+ divMod := self absFastDivMod:abs.
+ ] ifFalse:[
+ n := abs asLargeInteger.
+ ].
] ifFalse:[
- "
- if the argument is not a largeInteger, coerce
- "
- (cls == self class) ifFalse:[
- ^ self retry:#// coercing:aNumber
- ].
- n := aNumber
+ "
+ if the argument is not a largeInteger, coerce
+ "
+ (cls == self class) ifFalse:[
+ ^ self retry:#// coercing:aNumber
+ ].
+ n := aNumber
].
divMod isNil ifTrue:[
- divMod := self absDivMod:n.
+ divMod := self absDivMod:n.
].
quo := divMod at:1.
(sign == aNumber sign) ifFalse:[
- "/ adjust for truncation if negative and there is a remainder ...
- "/ be careful: there is one special case to care for here:
- "/ if quo is maxInt+1, the negation can be represented as a smallInt.
- quo := quo sign:-1.
- (divMod at:2) == 0 ifFalse:[
- ^ quo - 1
- ].
- quo digitLength == SmallInteger maxBytes ifTrue:[
- ^ quo compressed
- ].
+ "/ adjust for truncation if negative and there is a remainder ...
+ "/ be careful: there is one special case to care for here:
+ "/ if quo is maxInt+1, the negation can be represented as a smallInt.
+ quo := quo sign:-1.
+ (divMod at:2) == 0 ifFalse:[
+ ^ quo - 1
+ ].
+ quo digitLength == SmallInteger maxBytes ifTrue:[
+ ^ quo compressed
+ ].
].
^ quo
@@ -882,139 +880,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
@@ -1036,29 +1034,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
@@ -1090,11 +1088,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
].
^ (LargeInteger digitBytes:newBytes) compressed
@@ -1109,9 +1107,9 @@
bigNum1 := 2 raisedToInteger:512.
bigNum2 := 2 raisedToInteger:510.
Time millisecondsToRun:[
- 1000000 timesRepeat:[
- bigNum1 bitXor:bigNum2.
- ]
+ 1000000 timesRepeat:[
+ bigNum1 bitXor:bigNum2.
+ ]
]
"
!
@@ -1130,92 +1128,92 @@
idx0 := 1.
-%{
+%{
OBJ __digitByteArray = __INST(digitByteArray);
/*
* 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
@@ -1239,24 +1237,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
+ ]
]
"
@@ -1272,23 +1270,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
"
@@ -1335,27 +1333,27 @@
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
"
- (1 bitShift32:31) rotate32:0
- (1 bitShift32:31) rotate32:1
- (1 bitShift32:31) rotate32:-1
+ (1 bitShift32:31) rotate32:0
+ (1 bitShift32:31) rotate32:1
+ (1 bitShift32:31) rotate32:-1
"
!
@@ -1373,21 +1371,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
@@ -1433,10 +1431,10 @@
^ self class digitBytes:digitByteArray MSB:true
"
- (LargeInteger value:16r11223344) byteSwapped hexPrintString
- (LargeInteger value:16r44332211) byteSwapped hexPrintString
- 16r88776655 byteSwapped hexPrintString
- 16r11223344 byteSwapped hexPrintString
+ (LargeInteger value:16r11223344) byteSwapped hexPrintString
+ (LargeInteger value:16r44332211) byteSwapped hexPrintString
+ 16r88776655 byteSwapped hexPrintString
+ 16r11223344 byteSwapped hexPrintString
"
"Created: / 31-01-2012 / 11:07:42 / cg"
@@ -1660,6 +1658,9 @@
}
break;
case 7:
+# if defined(__LSBFIRST__)
+ _val = ((INT *)__digitBytes)[0] & 0x00FFFFFFFFFFFFFFL;
+# else
_val = (__digitBytes[6]<<8);
_val = (_val + __digitBytes[5]) << 8;
_val = (_val + __digitBytes[4]) << 8;
@@ -1667,45 +1668,66 @@
_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 defined(__LSBFIRST__)
+ _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];
+# endif
if (__INST(sign) == __mkSmallInteger(-1))
_val = -_val;
RETURN (__mkSmallInteger(_val));
case 5:
+# if defined(__LSBFIRST__)
+ _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];
+# endif
if (__INST(sign) == __mkSmallInteger(-1))
_val = -_val;
RETURN (__mkSmallInteger(_val));
case 4:
+# if defined(__LSBFIRST__)
+ _val = ((INT *)__digitBytes)[0] & 0x00000000FFFFFFFFL;
+# else
_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 defined(__LSBFIRST__)
+ _val = ((int *)__digitBytes)[0] & 0x00FFFFFF;
+# else
_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 defined(__LSBFIRST__)
+ _val = ((int *)__digitBytes)[0] & 0x0000FFFF;
+# else
_val = (__digitBytes[1]<<8) + __digitBytes[0];
+# endif
if (__INST(sign) == __mkSmallInteger(-1))
_val = -_val;
RETURN (__mkSmallInteger(_val));
@@ -1730,20 +1752,32 @@
_val = -_val;
RETURN (__mkSmallInteger(_val));
}
+# if defined(__LSBFIRST__)
+ _val = ((int *)__digitBytes)[0] & 0x0000FFFF;
+# else
_val = (__digitBytes[1]<<8) + __digitBytes[0];
+# endif
if (__INST(sign) == __mkSmallInteger(-1))
_val = -_val;
RETURN (__mkSmallInteger(_val));
}
if (_idx == 3) {
+# if defined(__LSBFIRST__)
+ _val = ((int *)__digitBytes)[0] & 0x00FFFFFF;
+# else
_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 defined(__LSBFIRST__)
+ _val = ((int *)__digitBytes)[0];
+# else
_val = (((((_val<<8) + __digitBytes[2])<<8) + __digitBytes[1])<<8) + __digitBytes[0];
+# endif
if (__INST(sign) == __mkSmallInteger(-1))
_val = -_val;
if (__ISVALIDINTEGER(_val)) {
@@ -1758,7 +1792,7 @@
}
/*
- * must copy & cut off some bytes
+ * must copy & cut off some (zero)bytes
*/
{
OBJ newDigits;
@@ -1929,41 +1963,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
@@ -2508,7 +2542,7 @@
"
16r7FFFFFFF + 1 -> 2147483648
- 16r7FFFFFFF plus32: 1 -> -2147483648
+ 16r7FFFFFFF plus32: 1 -> -2147483648
"
! !
@@ -2593,7 +2627,7 @@
%{ /* NOCONTEXT */
if (__isLargeInteger(aLargeInteger)) {
- OBJ _digitByteArray = __INST(digitByteArray);
+ OBJ _digitByteArray = __INST(digitByteArray);
OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
if (__isByteArray(_digitByteArray)
@@ -3810,10 +3844,10 @@
].
lastDigit := resultDigitByteArray basicAt:lResult.
].
- (lastDigit ~~ 0 and:[lResult > SmallInteger maxBytes]) ifTrue:[
- ^ result
+ (lastDigit == 0 or:[lResult <= SmallInteger maxBytes]) ifTrue:[
+ ^ result compressed.
].
- ^ result compressed
+ ^ result
"Modified: 5.11.1996 / 14:09:25 / cg"
!
@@ -5172,10 +5206,10 @@
!LargeInteger class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.206 2013-04-25 07:12:35 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.209 2013-05-21 20:44:47 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.206 2013-04-25 07:12:35 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.209 2013-05-21 20:44:47 cg Exp $'
! !