--- a/SmallInteger.st Fri Nov 13 21:00:19 2015 +0100
+++ b/SmallInteger.st Tue Nov 17 11:31:37 2015 +0100
@@ -963,6 +963,7 @@
! !
+
!SmallInteger methodsFor:'bit operators'!
bitAnd:anInteger
@@ -1043,7 +1044,9 @@
bitClear:anInteger
"return the bitwise-and of the receiver and the complement of the argument, anInteger,
- returning the receiver with bits of the argument cleared."
+ returning the receiver with bits of the argument cleared.
+ The method's name may be misleading: the receiver is not changed,
+ but a new number is returned. Should be named #withBitCleared:"
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
@@ -1051,7 +1054,7 @@
#else
/* anding the tags doesn't change it */
if (__isSmallInteger(anInteger)) {
- RETURN ( ((OBJ) (((INT)self & ~(INT)anInteger) | TAG_INT)) );
+ RETURN ( ((OBJ) (((INT)self & ~(INT)anInteger) | TAG_INT)) );
}
#endif /* not __SCHTEAM__ */
%}.
@@ -1067,36 +1070,62 @@
"return the number of 1-bits in the receiver"
%{ /* NOCONTEXT */
-#ifndef __SCHTEAM__
+#ifdef __SCHTEAM__
+ long _v1, _v2;
+ long _self = self.longValue();
+
+ _v1 = _self & 0xFFFFFFFF;
+ _v1 = _v1 - ((_v1 >> 1) & 0x55555555);
+ _v1 = (_v1 & 0x33333333) + ((_v1 >> 2) & 0x33333333);
+ _v1 = ((_v1 + (_v1 >> 4)) & 0x0F0F0F0F);
+
+ _v2 = (unsigned int)(_self >> 32);
+ _v2 = _v2 - ((_v2 >> 1) & 0x55555555);
+ _v2 = (_v2 & 0x33333333) + ((_v2 >> 2) & 0x33333333);
+ _v2 = ((_v2 + (_v2 >> 4)) & 0x0F0F0F0F);
+
+ _cnt = ((_v1 * 0x01010101) >> 24) + ((_v2 * 0x01010101) >> 24);
+ return __c__._RETURN( STInteger._qnew( _cnt ) );
+#else
unsigned int _cnt;
- unsigned INT _self = __intVal(self);
-
-# define ALGORIHTM_3
+
+ // popcnt is slower
+# if 0 // defined(__GNUC__) && (defined(__x86__) || defined(__x86_64__))
+# define ALGORIHTM_4
+# else
+# define ALGORIHTM_3
+# endif
# ifdef ALGORITHM_1
// old k&r code; might be better if only one or two bits are set
+ unsigned INT _self = __intVal(self);
+
_cnt = 0;
while (_self) {
- _cnt++;
- _self = _self & (_self - 1);
+ _cnt++;
+ _self = _self & (_self - 1);
}
# else
+
# ifdef ALGORITHM_2
// seems to be faster on the average (and has better worst case)
static unsigned char table[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+ unsigned INT _self = __intVal(self);
_cnt = 0;
while (_self) {
- _cnt += table[ _self & 0x0F ];
- _self >>= 4;
+ _cnt += table[ _self & 0x0F ];
+ _self >>= 4;
}
# else
+
# ifdef ALGORIHTM_3
// the fastest, but hard (impossible) to understand (google for fastest bit count)
# if __POINTER_SIZE__ == 8
unsigned int _v1, _v2;
+ unsigned INT _self = __intVal(self);
_v1 = _self & 0xFFFFFFFF;
_v1 = _v1 - ((_v1 >> 1) & 0x55555555);
@@ -1116,7 +1145,45 @@
_cnt = (_cnt * 0x01010101) >> 24;
# endif
# else
- error error error
+
+# ifdef ALGORIHTM_4
+ // using the popcnt instruction (x86 only); strange enough, this is slower than ALGO3
+# if __POINTER_SIZE__ == 8
+ unsigned INT _v;
+
+# define _POPCNT(__op) \
+ ({ \
+ INT __rslt; \
+ asm("xor %%rax,%%rax \n \
+ popcnt %1,%%rax \n \
+ " : "=a" (__rslt) \
+ : "g" ((INT)(__op)) \
+ : "cc"); \
+ (OBJ)__rslt; \
+ })
+
+ _v = (INT)self;
+ _cnt = _POPCNT(_v);
+ _cnt--; // one too many due to tag
+# else
+# define _POPCNT(__op) \
+ ({ \
+ INT __rslt; \
+ asm("xor %%eax,%%eax \n \
+ popcnt %1,%%eax \n \
+ " : "=a" (__rslt) \
+ : "g" ((INT)(__v)) \
+ : "cc"); \
+ (OBJ)__rslt; \
+ })
+
+ _v = (INT)self;
+ _cnt = _POPCNT(_v);
+ _cnt--; // one too many due to tag
+# endif
+# else
+ error error error
+# endif
# endif
# endif
# endif
@@ -1129,25 +1196,37 @@
"
1 to:1000000 do:[:n |
- self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
+ self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
].
- #(
- 16r00010000 16r00100000 16r01000000 16r10000000
- 16r00020000 16r00200000 16r02000000 16r20000000
- 16r00040000 16r00400000 16r04000000 16r40000000
- 16r00080000 16r00800000 16r08000000 16r80000000
-
- 16rFFFFFFFF 16r7FFFFFFF 16r3FFFFFFF 16r1FFFFFFF
- 16rEEEEEEEE 16r7EEEEEEE 16r3EEEEEEE 16r1EEEEEEE
- 16rDDDDDDDD 16r7DDDDDDD 16r3DDDDDDD 16r1DDDDDDD
- 16rCCCCCCCC 16r7CCCCCCC 16r3CCCCCCC 16r1CCCCCCC
+ #( 16r00000000
+ 16r00010000 16r00100000 16r01000000 16r10000000
+ 16r00020000 16r00200000 16r02000000 16r20000000
+ 16r00040000 16r00400000 16r04000000 16r40000000
+ 16r00080000 16r00800000 16r08000000 16r80000000
+
+ 16rFFFFFFFF 16r7FFFFFFF 16r3FFFFFFF 16r1FFFFFFF
+ 16rEEEEEEEE 16r7EEEEEEE 16r3EEEEEEE 16r1EEEEEEE
+ 16rDDDDDDDD 16r7DDDDDDD 16r3DDDDDDD 16r1DDDDDDD
+ 16rCCCCCCCC 16r7CCCCCCC 16r3CCCCCCC 16r1CCCCCCC
+
+ 16r8000000000010000 16r8000000000100000 16r8000000001000000 16r8000000010000000
+ 16r8000000000020000 16r8000000000200000 16r8000000002000000 16r8000000020000000
+ 16r8000000000040000 16r8000000000400000 16r8000000004000000 16r8000000040000000
+ 16r8000000000080000 16r8000000000800000 16r8000000008000000 16r8000000080000000
+
+ 16r80000000FFFFFFFF 16r800000007FFFFFFF 16r800000003FFFFFFF 16r800000001FFFFFFF
+ 16r80000000EEEEEEEE 16r800000007EEEEEEE 16r800000003EEEEEEE 16r800000001EEEEEEE
+ 16r80000000DDDDDDDD 16r800000007DDDDDDD 16r800000003DDDDDDD 16r800000001DDDDDDD
+ 16r80000000CCCCCCCC 16r800000007CCCCCCC 16r800000003CCCCCCC 16r800000001CCCCCCC
+
+ 16rFFFFFFFFFFFFFFFF 16r7FFFFFFFFFFFFFFF 16r3FFFFFFFFFFFFFFF 16r1FFFFFFFFFFFFFFF
) do:[:n |
- self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
+ self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
]
1 to:10000000 do:[:n |
- (n bitCount)
+ (n bitCount)
]
"
@@ -1155,14 +1234,18 @@
!
bitInvert
- "return the value of the receiver with all bits inverted"
+ "return the value of the receiver with all bits inverted.
+ The method's name may be misleading: the receiver is not changed,
+ but a new number is returned. Could be named #withBitsInverted"
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
+ long _self = self.longValue();
+ return __c__._RETURN( STInteger._new( ~_self ) );
#else
/* invert anything except tag bits */
RETURN ( ((OBJ) ((INT)self ^ ~TAG_MASK)) );
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ super bitInvert
!
@@ -1176,9 +1259,9 @@
#else
/* oring the tags doesn't change it */
if (__isSmallInteger(anInteger)) {
- RETURN ( ((OBJ) ((INT)self | (INT)anInteger)) );
+ RETURN ( ((OBJ) ((INT)self | (INT)anInteger)) );
}
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ self retry:#bitOr: coercing:anInteger
@@ -1190,6 +1273,155 @@
"
!
+bitReversed
+ "swap (i.e. reverse) bits in an integer
+ i.e. a.b.c.d....x.y.z -> z.y.x...b.a.d.c."
+
+%{ /* NOCONTEXT */
+#ifndef __SCHTEAM__
+ unsigned INT v = __intVal(self);
+
+# if __POINTER_SIZE__ == 8
+ // swap odd and even bits
+ v = ((v >> 1) & 0x5555555555555555) | ((v & 0x5555555555555555) << 1);
+ // swap consecutive pairs
+ v = ((v >> 2) & 0x3333333333333333) | ((v & 0x3333333333333333) << 2);
+ // swap nibbles ...
+ v = ((v >> 4) & 0x0F0F0F0F0F0F0F0F) | ((v & 0x0F0F0F0F0F0F0F0F) << 4);
+ // swap bytes
+ v = ((v >> 8) & 0x00FF00FF00FF00FF) | ((v & 0x00FF00FF00FF00FF) << 8);
+ // swap 2-byte pairs
+ v = ((v >> 16) & 0x0000FFFF0000FFFF) | (( v & 0x0000FFFF0000FFFF) << 16);
+ // swap 4-byte long pairs
+ v = ((v >> 32) & 0x00000000FFFFFFFF) | (( v & 0x00000000FFFFFFFF) << 32);
+# else
+ // swap odd and even bits
+ v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
+ // swap consecutive pairs
+ v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
+ // swap nibbles ...
+ v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
+ // swap bytes
+ v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
+ // swap 2-byte long pairs
+ v = ((v >> 16) & 0x0000FFFF) | ((v & 0x0000FFFF) << 16);
+# endif
+
+ if (v <= _MAX_INT) {
+ RETURN ( __mkSmallInteger(v) );
+ }
+ RETURN (__MKUINT(v));
+#endif /* not __SCHTEAM__ */
+%}.
+ ^ super bitReversed
+
+ "
+ 2r1001 bitReversed printStringRadix:2
+ 2r100111010011 bitReversed printStringRadix:2
+ -1 bitReversed printStringRadix:2
+ "
+!
+
+bitReversed16
+ "swap (i.e. reverse) the low 16 bits in an integer
+ the high bits are ignored and clear in the result
+ i.e. xxx.a.b.c.d....x.y.z -> 000.z.y.x...b.a.d.c."
+
+%{ /* NOCONTEXT */
+#ifndef __SCHTEAM__
+ unsigned INT v = __intVal(self) & 0xFFFF;
+
+ // swap odd and even bits
+ v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
+ // swap consecutive pairs
+ v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
+ // swap nibbles ...
+ v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
+ // swap bytes
+ v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
+
+ if (v <= _MAX_INT) {
+ RETURN ( __mkSmallInteger(v) );
+ }
+ RETURN (__MKUINT(v));
+#endif /* not __SCHTEAM__ */
+%}.
+ ^ super bitReversed16
+
+ "
+ 2r1001 bitReversed16 printStringRadix:2
+ 2r100111010011 bitReversed16 printStringRadix:2
+ -1 bitReversed16 printStringRadix:2
+ "
+!
+
+bitReversed32
+ "swap (i.e. reverse) the low 32 bits in an integer
+ the high bits are ignored and clear in the result
+ i.e. xxx.a.b.c.d....x.y.z -> 000.z.y.x...b.a.d.c."
+
+%{ /* NOCONTEXT */
+#ifndef __SCHTEAM__
+ unsigned INT v = __intVal(self) & 0xFFFFFFFF;
+
+ // swap odd and even bits
+ v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
+ // swap consecutive pairs
+ v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
+ // swap nibbles ...
+ v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
+ // swap bytes
+ v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
+ // swap 2-byte long pairs
+ v = ((v >> 16) & 0x0000FFFF) | ((v & 0x0000FFFF) << 16);
+
+ if (v <= _MAX_INT) {
+ RETURN ( __mkSmallInteger(v) );
+ }
+ RETURN (__MKUINT(v));
+#endif /* not __SCHTEAM__ */
+%}.
+ ^ super bitReversed32
+
+ "
+ 2r1001 bitReversed32 printStringRadix:2
+ 2r100111010011 bitReversed32 printStringRadix:2
+ -1 bitReversed32 printStringRadix:2
+ "
+!
+
+bitReversed8
+ "swap (i.e. reverse) the low 8 bits in an integer
+ the high bits are ignored and clear in the result
+ i.e. xxx.a.b.c.d....x.y.z -> 000.z.y.x...b.a.d.c."
+
+%{ /* NOCONTEXT */
+#ifndef __SCHTEAM__
+ unsigned INT v = __intVal(self) & 0xFF;
+
+ // swap odd and even bits
+ v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
+ // swap consecutive pairs
+ v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
+ // swap nibbles ...
+ v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
+
+ if (v <= _MAX_INT) {
+ RETURN ( __mkSmallInteger(v) );
+ }
+ RETURN (__MKUINT(v));
+#endif /* not __SCHTEAM__ */
+%}.
+ ^ super bitReversed8
+
+ "
+ 2r1001 bitReversed8 printStringRadix:2
+ 2r10011101 bitReversed8 printStringRadix:2
+ 2r111110011101 bitReversed8 printStringRadix:2
+ -1 bitReversed8 printStringRadix:2
+ "
+!
+
bitShift:shiftCount
"return the value of the receiver shifted by shiftCount bits;
leftShift if shiftCount > 0; rightShift otherwise.
@@ -1324,28 +1556,27 @@
clearBit:anInteger
"return a new integer where the specified bit is off.
Bits are counted from 1 starting with the least significant.
- The methods name may be misleading: the receiver is not changed,
+ The method's name may be misleading: the receiver is not changed,
but a new number is returned. Should be named #withBitCleared:"
%{ /* NOCONTEXT */
-#ifdef __SCHTEAM__
-#else
+#ifndef __SCHTEAM__
if (__isSmallInteger(anInteger)) {
- int index = __intVal(anInteger);
-
- if (index > 0) {
+ int index = __intVal(anInteger);
+
+ if (index > 0) {
# if __POINTER_SIZE__ == 8
- if (index <= 62)
+ if (index <= 62)
# else
- if (index <= 30)
+ if (index <= 30)
# endif
- {
- INT mask = __MASKSMALLINT(1 << (index-1));
-
- RETURN ( ((OBJ) ((INT)self & ~(INT)mask)) );
- }
- RETURN (self); /* nothing to do ... */
- }
+ {
+ INT mask = __MASKSMALLINT(1 << (index-1));
+
+ RETURN ( ((OBJ) ((INT)self & ~(INT)mask)) );
+ }
+ RETURN (self); /* nothing to do ... */
+ }
}
#endif /* not __SCHTEAM__ */
%}.
@@ -1507,27 +1738,26 @@
invertBit:anInteger
"return a new number where the specified bit is inverted.
Bits are counted from 1 starting with the least significant.
- The methods name may be misleading: the receiver is not changed,
+ The method's name may be misleading: the receiver is not changed,
but a new number is returned. Should be named #withBitInverted:"
%{ /* NOCONTEXT */
-#ifdef __SCHTEAM__
-#else
+#ifndef __SCHTEAM__
if (__isSmallInteger(anInteger)) {
- int index = __intVal(anInteger);
-
- if (index > 0) {
+ int index = __intVal(anInteger);
+
+ if (index > 0) {
# if __POINTER_SIZE__ == 8
- if (index <= 62)
+ if (index <= 62)
# else
- if (index <= 30)
+ if (index <= 30)
# endif
- {
- INT mask = __MASKSMALLINT(1 << (index-1));
-
- RETURN ( ((OBJ) ((INT)self ^ (INT)mask)) );
- }
- }
+ {
+ INT mask = __MASKSMALLINT(1 << (index-1));
+
+ RETURN ( ((OBJ) ((INT)self ^ (INT)mask)) );
+ }
+ }
}
#endif /* not __SCHTEAM__ */
%}.
@@ -1757,27 +1987,26 @@
setBit:anInteger
"return a new integer where the specified bit is on.
Bits are counted from 1 starting with the least significant.
- The methods name may be misleading: the receiver is not changed,
+ The method's name may be misleading: the receiver is not changed,
but a new number is returned. Should be named #withBitSet:"
%{ /* NOCONTEXT */
-#ifdef __SCHTEAM__
-#else
+#ifndef __SCHTEAM__
if (__isSmallInteger(anInteger)) {
- int index = __intVal(anInteger);
-
- if (index > 0) {
+ int index = __intVal(anInteger);
+
+ if (index > 0) {
# if __POINTER_SIZE__ == 8
- if (index <= 62)
+ if (index <= 62)
# else
- if (index <= 30)
+ if (index <= 30)
# endif
- {
- INT mask = __MASKSMALLINT(1 << (index-1));
-
- RETURN ( ((OBJ) ((INT)self | (INT)mask)) );
- }
- }
+ {
+ INT mask = __MASKSMALLINT(1 << (index-1));
+
+ RETURN ( ((OBJ) ((INT)self | (INT)mask)) );
+ }
+ }
}
#endif /* not __SCHTEAM__ */
%}.
@@ -1828,7 +2057,7 @@
swapped = ((v>>8)&0xFF) | ((v & 0xFF)<<8);
RETURN (__mkSmallInteger(swapped));
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ super byteSwapped16
@@ -1938,11 +2167,11 @@
// xxxxxxxx xxxxxxxx
// xxxxxxxx xxxxxxxx
swapped = (v>>56) | ((v>>40)&0xFF00) | ((v>>24) & 0xFF0000) | ((v>>8) & 0xFF000000)
- | ((v & 0xFF000000)<<8) | ((v & 0x00FF0000)<<24) | ((v & 0x0000FF00)<<40)
- | ((v & 0xFF)<<56);
+ | ((v & 0xFF000000)<<8) | ((v & 0x00FF0000)<<24) | ((v & 0x0000FF00)<<40)
+ | ((v & 0xFF)<<56);
# endif
RETURN(__MKUINT( swapped ));
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ super byteSwapped64
@@ -2409,7 +2638,9 @@
swapBytes
"swap bytes pair-wise in a positive integer
i.e. a.b.c.d -> b.a.d.c.
-
+ The name may be misleading; actually a new integer is returned,
+ and the receiver is not modified.
+
Redefined here for speed.
Swapping of negative integers is undefined and therefore not supported.
This case is handled in the superclass."
@@ -2419,19 +2650,19 @@
unsigned INT v = __intVal(self);
if ((INT)v >= 0) {
- unsigned INT swapped;
+ unsigned INT swapped;
# if __POINTER_SIZE__ == 8
- swapped = ((v >> 8) & 0x00FF00FF00FF00FF) | ((v & 0x00FF00FF00FF00FF) << 8);
+ swapped = ((v >> 8) & 0x00FF00FF00FF00FF) | ((v & 0x00FF00FF00FF00FF) << 8);
# else
- swapped = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
+ swapped = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
# endif /* __POINTER_SIZE__ */
- //if (__ISVALIDINTEGER(swapped)) { // sorry, but this does not work here if (INT)swapped would be negative
- if (swapped <= _MAX_INT) {
- RETURN ( __mkSmallInteger(swapped) );
- }
- RETURN (__MKUINT(swapped));
+ //if (__ISVALIDINTEGER(swapped)) { // sorry, but this does not work here if (INT)swapped would be negative
+ if (swapped <= _MAX_INT) {
+ RETURN ( __mkSmallInteger(swapped) );
+ }
+ RETURN (__MKUINT(swapped));
}
#endif
%}.
@@ -2482,13 +2713,18 @@
!SmallInteger methodsFor:'coercing & converting'!
asCharacter
- "Return a character with the receiver as ascii value"
+ "Return a character with the receiver as ascii (actually: unicode) value"
^ Character value:self
+
+ "
+ Character value:16r61
+ Character value:16r161
+ "
!
asFloat
- "return a Float with same value as receiver.
+ "return a Float with same value as the receiver.
Redefined for performance (machine can do it faster)"
%{ /* NOCONTEXT */
@@ -2506,7 +2742,11 @@
!
asLargeInteger
- "return a LargeInteger with same value as receiver"
+ "return a LargeInteger with same value as receiver.
+ Not for general use:
+ Notice, that this returns an unnormalized large int (i.e. a large with a smallint value),
+ which are normally not present in the system, and not handled correctly by many functions.
+ This exists only as a helper for some algorithms and converters"
^ LargeInteger value:self
!
@@ -2531,12 +2771,12 @@
!
asUnsignedInt
- "return an integer representing my unsigned INT
- value. Notice, that the returned integer's size
+ "return an integer representing my unsigned INT value.
+ Notice, that the returned integer's size
depends heavily on the underlying INT size;
You will get 16rFFFFFFFF on 32bit machines,
but 16rFFFFFFFFFFFFFFFF on 64 bit machines.
- So use this only for printing."
+ So use this only for printing or certain bit operations (emulating C semantics)."
%{ /* NOCONTEXT */
INT iVal = __intVal(self);
@@ -2687,16 +2927,16 @@
#else
if (__isSmallInteger(aNumber)) {
# ifdef POSITIVE_ADDRESSES
- RETURN ( (__intVal(self) < __intVal(aNumber)) ? true : false );
+ RETURN ( (__intVal(self) < __intVal(aNumber)) ? true : false );
# else
- /* tag bit does not change ordering */
- RETURN ( ((INT)self < (INT)aNumber) ? true : false );
+ /* tag bit does not change ordering */
+ RETURN ( ((INT)self < (INT)aNumber) ? true : false );
# endif
}
if (__isFloatLike(aNumber)) {
- RETURN ( ((double)__intVal(self) < __floatVal(aNumber)) ? true : false );
+ RETURN ( ((double)__intVal(self) < __floatVal(aNumber)) ? true : false );
}
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ aNumber lessFromInteger:self
"^ self retry:#< coercing:aNumber"
@@ -2712,16 +2952,16 @@
if (__isSmallInteger(aNumber)) {
# ifdef POSITIVE_ADDRESSES
- RETURN ( (__intVal(self) <= __intVal(aNumber)) ? true : false );
+ RETURN ( (__intVal(self) <= __intVal(aNumber)) ? true : false );
# else
- /* tag bit does not change ordering */
- RETURN ( ((INT)self <= (INT)aNumber) ? true : false );
+ /* tag bit does not change ordering */
+ RETURN ( ((INT)self <= (INT)aNumber) ? true : false );
# endif
}
if (__isFloatLike(aNumber)) {
- RETURN ( ((double)__intVal(self) <= __floatVal(aNumber)) ? true : false );
+ RETURN ( ((double)__intVal(self) <= __floatVal(aNumber)) ? true : false );
}
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ (self > aNumber) not
@@ -2735,25 +2975,25 @@
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
if (aNumber.isNumber()) {
- return context._RETURN( self.eqvP( aNumber ));
+ return context._RETURN( aNumber.eqvP( self.longValue() ));
}
#else
if (aNumber == self) {
- RETURN ( true );
+ RETURN ( true );
}
if (! __isNonNilObject(aNumber)) {
- /* a smallint or nil */
- RETURN ( false );
+ /* a smallint or nil */
+ RETURN ( false );
}
if (__qIsFloatLike(aNumber)) {
- RETURN ( ((double)__intVal(self) == __floatVal(aNumber)) ? true : false );
+ RETURN ( ((double)__intVal(self) == __floatVal(aNumber)) ? true : false );
}
if (__qIsShortFloat(aNumber)) {
- RETURN ( ((double)__intVal(self) == __shortFloatVal(aNumber)) ? true : false );
+ RETURN ( ((double)__intVal(self) == __shortFloatVal(aNumber)) ? true : false );
}
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ aNumber equalFromInteger:self
!
@@ -2768,16 +3008,16 @@
if (__isSmallInteger(aNumber)) {
# ifdef POSITIVE_ADDRESSES
- RETURN ( (__intVal(self) > __intVal(aNumber)) ? true : false );
+ RETURN ( (__intVal(self) > __intVal(aNumber)) ? true : false );
# else
- /* tag bit does not change ordering */
- RETURN ( ((INT)self > (INT)aNumber) ? true : false );
+ /* tag bit does not change ordering */
+ RETURN ( ((INT)self > (INT)aNumber) ? true : false );
# endif
}
if (__isFloatLike(aNumber)) {
- RETURN ( ((double)__intVal(self) > __floatVal(aNumber)) ? true : false );
+ RETURN ( ((double)__intVal(self) > __floatVal(aNumber)) ? true : false );
}
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ (aNumber < self)
@@ -2794,16 +3034,16 @@
if (__isSmallInteger(aNumber)) {
# ifdef POSITIVE_ADDRESSES
- RETURN ( (__intVal(self) >= __intVal(aNumber)) ? true : false );
+ RETURN ( (__intVal(self) >= __intVal(aNumber)) ? true : false );
# else
- /* tag bit does not change ordering */
- RETURN ( ((INT)self >= (INT)aNumber) ? true : false );
+ /* tag bit does not change ordering */
+ RETURN ( ((INT)self >= (INT)aNumber) ? true : false );
# endif
}
if (__isFloatLike(aNumber)) {
- RETURN ( ((double)__intVal(self) >= __floatVal(aNumber)) ? true : false );
+ RETURN ( ((double)__intVal(self) >= __floatVal(aNumber)) ? true : false );
}
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ (self < aNumber) not
@@ -2852,23 +3092,23 @@
if (__isSmallInteger(aNumber)) {
# if TAG_INT == 1
- /* tag bit does not change ordering */
- if ((INT)(self) > (INT)(aNumber))
+ /* tag bit does not change ordering */
+ if ((INT)(self) > (INT)(aNumber))
# else
- if (__intVal(self) > __intVal(aNumber))
+ if (__intVal(self) > __intVal(aNumber))
# endif
- {
- RETURN ( self );
- }
- RETURN ( aNumber );
+ {
+ RETURN ( self );
+ }
+ RETURN ( aNumber );
}
if (__isFloatLike(aNumber)) {
- if ( (double)__intVal(self) > __floatVal(aNumber) ) {
- RETURN ( self );
- }
- RETURN ( aNumber );
+ if ( (double)__intVal(self) > __floatVal(aNumber) ) {
+ RETURN ( self );
+ }
+ RETURN ( aNumber );
}
-#endif
+#endif /* not __SCHTEAM__ */
%}.
"/ fallback for non-smallInteger argument
@@ -2884,23 +3124,23 @@
if (__isSmallInteger(aNumber)) {
# if TAG_INT == 1
- /* tag bit does not change ordering */
- if ((INT)(self) < (INT)(aNumber))
+ /* tag bit does not change ordering */
+ if ((INT)(self) < (INT)(aNumber))
# else
- if (__intVal(self) < __intVal(aNumber))
+ if (__intVal(self) < __intVal(aNumber))
# endif
- {
- RETURN ( self );
- }
- RETURN ( aNumber );
+ {
+ RETURN ( self );
+ }
+ RETURN ( aNumber );
}
if (__isFloatLike(aNumber)) {
- if ( (double)__intVal(self) < __floatVal(aNumber) ) {
- RETURN ( self );
- }
- RETURN ( aNumber );
+ if ( (double)__intVal(self) < __floatVal(aNumber) ) {
+ RETURN ( self );
+ }
+ RETURN ( aNumber );
}
-#endif
+#endif /* not __SCHTEAM__ */
%}.
"/ fallback for non-smallInteger argument
@@ -2914,26 +3154,26 @@
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
if (aNumber.isNumber()) {
- return context._RETURN( (self.eqvP( aNumber ) == STObject.True) ? STObject.False : STObject.True);
- /* NOTREACHED */
+ return context._RETURN( (aNumber.eqv( self.longValue() )) ? STObject.False : STObject.True);
+ /* NOTREACHED */
}
#else
if (aNumber == self) {
- RETURN ( false );
+ RETURN ( false );
}
if (! __isNonNilObject(aNumber)) {
- /* a smallint or nil */
- RETURN ( true );
+ /* a smallint or nil */
+ RETURN ( true );
}
if (__qIsFloatLike(aNumber)) {
- RETURN ( ((double)__intVal(self) != __floatVal(aNumber)) ? true : false );
+ RETURN ( ((double)__intVal(self) != __floatVal(aNumber)) ? true : false );
}
if (__qIsShortFloat(aNumber)) {
- RETURN ( ((double)__intVal(self) != __shortFloatVal(aNumber)) ? true : false );
+ RETURN ( ((double)__intVal(self) != __shortFloatVal(aNumber)) ? true : false );
}
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ (self = aNumber) not
! !
@@ -2969,7 +3209,6 @@
! !
-
!SmallInteger methodsFor:'iteration'!
timesRepeat:aBlock
@@ -4255,14 +4494,15 @@
setSign:aNumber
"private: for protocol completeness with LargeIntegers.
- Returns a smallInteger with my absValue and the sign of the argument"
-
+ Returns a smallInteger with my absValue and the sign of the argument.
+ The method's name may be misleading: the receiver is not changed,
+ but a new number is returned."
|absVal|
absVal := self abs.
aNumber < 0 ifTrue:[
- ^ absVal negated
+ ^ absVal negated
].
aNumber == 0 ifTrue:[^ 0].
^ absVal
@@ -4280,7 +4520,9 @@
sign:aNumber
<resource: #obsolete>
"private: for protocol completeness with LargeIntegers.
- Returns a smallInteger with my absValue and the sign of the argument"
+ Returns a smallInteger with my absValue and the sign of the argument.
+ The method's name may be misleading: the receiver is not changed,
+ but a new number is returned."
^ self setSign:aNumber
@@ -4935,31 +5177,35 @@
#ifndef __SCHTEAM__
// tricky, but very fast (google for it, to understand)
-# if __POINTER_SIZE__ == 4
- unsigned int v = __intVal(self);
-
+ unsigned INT v = __intVal(self);
+
+# if __POINTER_SIZE__ == 8
+ v ^= v >> 32;
+# endif
v ^= v >> 16;
v ^= v >> 8;
v ^= v >> 4;
v &= 0xf;
RETURN ( ( (0x6996 >> v) & 1 ) ? true : false );
-# endif
#endif
%}.
^ super parityOdd
"
- self assert:
- (((0 to:255) collect:[:i | i parityOdd ifTrue:1 ifFalse:0])
- asByteArray collect:[:c | c + $0 asciiValue]) asString
- =
- '0110100110010110100101100110100110010110011010010110100110010110100101100110100101101001100101100110100110010110100101100110100110010110011010010110100110010110011010011001011010010110011010010110100110010110100101100110100110010110011010010110100110010110'
-
- self assert:(16r0FFFFFFF parityOdd = 16r0FFFFFFF bitCount odd).
- self assert:(16r1FFFFFFF parityOdd = 16r1FFFFFFF bitCount odd).
- self assert:(16r3FFFFFFF parityOdd = 16r3FFFFFFF bitCount odd).
- self assert:(16r7FFFFFFF parityOdd = 16r7FFFFFFF bitCount odd).
- self assert:(16rFFFFFFFF parityOdd = 16rFFFFFFFF bitCount odd).
+ self assert:
+ (((0 to:255) collect:[:i | i parityOdd ifTrue:1 ifFalse:0])
+ asByteArray collect:[:c | c + $0 asciiValue]) asString
+ =
+ '0110100110010110100101100110100110010110011010010110100110010110100101100110100101101001100101100110100110010110100101100110100110010110011010010110100110010110011010011001011010010110011010010110100110010110100101100110100110010110011010010110100110010110'
+
+ self assert:(16r0FFFFFFF parityOdd = 16r0FFFFFFF bitCount odd).
+ self assert:(16r1FFFFFFF parityOdd = 16r1FFFFFFF bitCount odd).
+ self assert:(16r3FFFFFFF parityOdd = 16r3FFFFFFF bitCount odd).
+ self assert:(16r7FFFFFFF parityOdd = 16r7FFFFFFF bitCount odd).
+ self assert:(16rFFFFFFFF parityOdd = 16rFFFFFFFF bitCount odd).
+ self assert:(16r3FFFFFFFFFFFFFFF parityOdd = 16r3FFFFFFFFFFFFFFF bitCount odd).
+ self assert:(16r7FFFFFFFFFFFFFFF parityOdd = 16r7FFFFFFFFFFFFFFF bitCount odd).
+ self assert:(16rFFFFFFFFFFFFFFFF parityOdd = 16rFFFFFFFFFFFFFFFF bitCount odd).
"
"Modified (comment): / 09-01-2012 / 19:55:37 / cg"