--- a/Behavior.st Sat Nov 14 06:43:31 2015 +0100
+++ b/Behavior.st Wed Nov 18 06:57:38 2015 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1988 by Claus Gittinger
All Rights Reserved
@@ -25,7 +23,7 @@
!Behavior class methodsFor:'documentation'!
VS
- ^ '§Header: /cvs/stx/stx/libbasic/Behavior.st,v 1.315 2011/11/29 10:20:21 cg Exp §'
+ ^ '§Header: /cvs/stx/stx/libbasic/Behavior.st,v 1.315 2011/11/29 10:20:21 cg Exp §'
!
copyright
@@ -3101,9 +3099,10 @@
Behavior>>readFrom: and Behavior>>readFrom:onError:"
^ self
- readFromString:aString
- onError:[ self conversionErrorSignal
- raiseErrorString:'expected: ' , self name ]
+ readFromString:aString
+ onError:[
+ self conversionErrorSignal raiseErrorString:'expected: ' , self name
+ ]
"
Integer readFromString:'12345678901234567890'
--- a/CharacterArray.st Sat Nov 14 06:43:31 2015 +0100
+++ b/CharacterArray.st Wed Nov 18 06:57:38 2015 +0100
@@ -3472,6 +3472,23 @@
"
!
+asUUID
+ "return self as a UUID"
+
+ ^ UUID fromString:self
+
+ "
+ UUID genUUID asString asUUID
+ '{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}' asUUID
+ '{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}' asUnicodeString asUUID
+ 'EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B' asUUID
+ 'EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B quatsch' asUUID
+ 'quark EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B' asUUID
+ "
+
+ "Modified: / 02-08-2007 / 16:43:29 / cg"
+!
+
asUnicode16String
"return the receiver in a two-byte per character representation.
Normally, the internal ST/X representation should be transparent and not
--- a/Integer.st Sat Nov 14 06:43:31 2015 +0100
+++ b/Integer.st Wed Nov 18 06:57:38 2015 +0100
@@ -753,6 +753,8 @@
"Modified: / 15.11.1999 / 20:35:20 / cg"
! !
+
+
!Integer class methodsFor:'class initialization'!
initialize
@@ -798,6 +800,7 @@
"Modified: 18.7.1996 / 12:26:38 / cg"
! !
+
!Integer class methodsFor:'prime numbers'!
flushPrimeCache
@@ -1124,6 +1127,7 @@
^ self == Integer
! !
+
!Integer methodsFor:'*Roe'!
acceptRoeVisitor: aVisitor
@@ -1392,6 +1396,7 @@
"
! !
+
!Integer methodsFor:'bcd conversion'!
decodeFromBCD
@@ -4250,9 +4255,7 @@
nextPowerOf2
"return the power of 2 at or above the receiver.
Useful for padding.
- Notice: if you often need nextPowerOf2 of a largeInteger,
- you may wonna redefine it there using a much faster fill-with-1-bits algorithm
- (i.e. determine highbit, fill with ones, add one)."
+ Notice, that for a powerOf2, the receiver is returned."
|x t sh|
@@ -4284,7 +4287,14 @@
22 nextPowerOf2
12 factorial nextPowerOf2 isPowerOf:2
100 factorial nextPowerOf2 isPowerOf:2
- 1000 factorial nextPowerOf2 isPowerOf:2
+ 1000 factorial nextPowerOf2 isPowerOf:2
+ Time millisecondsToRun:[
+ |v|
+ v := 1000 factorial.
+ 1000 timesRepeat:[
+ v nextPowerOf2
+ ]
+ ]
"
!
@@ -4353,6 +4363,7 @@
"Created: / 09-01-2012 / 17:18:06 / cg"
! !
+
!Integer methodsFor:'special modulo arithmetic'!
add_32:anInteger
--- a/LargeInteger.st Sat Nov 14 06:43:31 2015 +0100
+++ b/LargeInteger.st Wed Nov 18 06:57:38 2015 +0100
@@ -316,6 +316,8 @@
"Modified: / 8.5.1998 / 21:40:41 / cg"
! !
+
+
!LargeInteger class methodsFor:'queries'!
isBuiltInClass
@@ -1609,7 +1611,7 @@
For positive receivers, this is the same as #digitAt:;
for negative ones, the actual bit representation is returned."
- |t digits|
+ |digits|
%{
#ifdef __SCHTEAM__
@@ -1617,25 +1619,24 @@
#endif
%}.
sign >= 0 ifTrue:[
- index > digitByteArray size ifTrue:[
- ^ 0
- ].
- ^ digitByteArray at:index.
+ index > digitByteArray size ifTrue:[
+ ^ 0
+ ].
+ ^ digitByteArray at:index.
].
"/ negative int - do 2's complement here
-
- t := self bitInvert + 1.
- t setSign:1.
- digits := t digitBytes.
+ digits := (self bitInvert + 1) digitBytes.
index > digits size ifTrue:[
- ^ 16rFF
+ ^ 16rFF
].
^ digits at:index.
"
16r11111111111111111111 negated digitByteAt:1
0 asLargeInteger digitByteAt:1
+ -1 asLargeInteger digitByteAt:1
+ -1 digitByteAt:1
"
"Created: / 25.10.1998 / 14:12:21 / cg"
@@ -1678,6 +1679,24 @@
"Modified: / 5.5.1999 / 14:57:03 / stefan"
!
+digitBytesSigned
+ "return a byteArray filled with the receiver's bits
+ (8 bits of the value (which may be negative) per element).
+ Least significant byte is first!!"
+
+ sign > 0 ifTrue:[
+ ^ digitByteArray
+ ].
+
+ "answer the 2's complement"
+ ^ (self bitInvert + 1) digitBytes.
+
+ "
+ 16r12345678901234567890 digitBytesSigned
+ -16r12345678901234567890 digitBytesSigned
+ "
+!
+
digitLength
"return the number bytes used by this Integer.
For negative receivers, the digitLength of its absolute value
@@ -4480,8 +4499,8 @@
|nr r1 r2|
nr := (3 raisedTo:exp) asInteger.
Transcript show:exp; show:' nbytes: '; showCR:nr digitLength;
- show:' normal: '; showCR:(Time microsecondsToRun:[ UseKarazuba := false. r1 := nr * nr ]);
- show:' karazuba: '; showCR:(Time microsecondsToRun:[ UseKarazuba := true. r2 := nr absMulKarazuba: nr ]).
+ 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).
]
"
@@ -5489,11 +5508,50 @@
^ self setSign:aNumber
! !
+!LargeInteger methodsFor:'queries'!
+
+nextPowerOf2
+ "return the power of 2 at or above the receiver.
+ Notice, that for a powerOf2, the receiver is returned."
+
+ |newBytes nBytes hi|
+
+ "/ assume I am normalized
+ 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).
+ ].
+ ^ (LargeInteger digitBytes:newBytes) + 1
+
+ "
+ 100 factorial nextPowerOf2 isPowerOf:2
+ 1000 factorial nextPowerOf2 isPowerOf:2
+ Time millisecondsToRun:[
+ |v|
+ v := 1000 factorial.
+ 1000 timesRepeat:[
+ v nextPowerOf2
+ ]
+ ]
+ "
+! !
+
!LargeInteger methodsFor:'testing'!
even
"return true if the receiver is even"
+%{
+#ifdef __SCHTEAM__
+ return context._RETURN( ((STLargeInteger)self).isEven() ? STObject.True : STObject.False);
+#endif
+%}.
^ (digitByteArray at:1) even
!
@@ -5511,6 +5569,11 @@
odd
"return true if the receiver is odd"
+%{
+#ifdef __SCHTEAM__
+ return context._RETURN( ((STLargeInteger)self).isEven() ? STObject.False : STObject.True);
+#endif
+%}.
^ (digitByteArray at:1) odd
"Modified: 18.11.1996 / 22:19:19 / cg"
--- a/SmallInteger.st Sat Nov 14 06:43:31 2015 +0100
+++ b/SmallInteger.st Wed Nov 18 06:57:38 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,34 +1070,61 @@
"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 = (_self >> 32) & 0xFFFFFFFF;
+ _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)
+ unsigned INT _self = __intVal(self);
+
# if __POINTER_SIZE__ == 8
unsigned int _v1, _v2;
@@ -1116,7 +1146,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 +1197,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 +1235,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 +1260,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 +1274,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 +1557,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 +1739,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 +1988,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 +2058,7 @@
swapped = ((v>>8)&0xFF) | ((v & 0xFF)<<8);
RETURN (__mkSmallInteger(swapped));
-#endif
+#endif /* not __SCHTEAM__ */
%}.
^ super byteSwapped16
@@ -1938,11 +2168,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 +2639,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 +2651,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 +2714,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 +2743,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 +2772,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 +2928,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 +2953,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 +2976,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 +3009,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 +3035,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 +3093,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 +3125,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 +3155,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 +3210,6 @@
! !
-
!SmallInteger methodsFor:'iteration'!
timesRepeat:aBlock
@@ -4255,14 +4495,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 +4521,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
@@ -4824,9 +5067,12 @@
"return true, if the receiver is even"
%{ /* NOCONTEXT */
-#ifndef __SCHTEAM__
+#ifdef __SCHTEAM__
+ return __c__._RETURN( self.isEven() ? STObject.True : STObject.False );
+ /* NOTREACHED */
+#else
RETURN ( ((INT)self & (INT)__MASKSMALLINT(1)) ? false : true );
-#endif
+#endif /* not SCHTEAM */
%}.
^ super even
!
@@ -4861,7 +5107,7 @@
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
- return context._RETURN( self.ltP(0) );
+ return context._RETURN( self.isLt_0() ? STObject.True : STObject.False);
/* NOTREACHED */
#else
# if TAG_INT == 1
@@ -4877,7 +5123,8 @@
nextPowerOf2
"return the power of 2 at or above the receiver.
- Useful for padding."
+ Useful for padding.
+ Notice, that for a powerOf2, the receiver is returned."
%{ /* NOCONTEXT */
#ifndef __SCHTEAM__
@@ -4898,6 +5145,7 @@
^ super nextPowerOf2
"
+ 0 nextPowerOf2
1 nextPowerOf2
2 nextPowerOf2
3 nextPowerOf2
@@ -4918,12 +5166,14 @@
"return true, if the receiver is odd"
%{ /* NOCONTEXT */
-#ifndef __SCHTEAM__
+#ifdef __SCHTEAM__
+ return __c__._RETURN( self.isEven() ? STObject.False : STObject.True );
+ /* NOTREACHED */
+#else
RETURN ( ((INT)self & (INT)__MASKSMALLINT(1)) ? true : false );
#endif
%}.
^ super odd
-
!
parityOdd
@@ -4935,31 +5185,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"
@@ -4971,7 +5225,8 @@
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
- return context._RETURN( (self.ltP(0) == STObject.True) ? STObject.False : STObject.True);
+ return context._RETURN( self.isGe_0() ? STObject.True : STObject.False);
+ /* NOTREACHED */
#else
# if TAG_INT == 1
@@ -5016,7 +5271,10 @@
reimplemented here for speed"
%{ /* NOCONTEXT */
-#ifndef __SCHTEAM__
+#ifdef __SCHTEAM__
+ return context._RETURN( self.isGt_0() ? STObject.True : STObject.False);
+ /* NOTREACHED */
+#else
# if TAG_INT == 1
/* tag bit does not change sign */
--- a/String.st Sat Nov 14 06:43:31 2015 +0100
+++ b/String.st Wed Nov 18 06:57:38 2015 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1988 by Claus Gittinger
All Rights Reserved
@@ -511,6 +509,7 @@
+
!String class methodsFor:'queries'!
defaultPlatformClass
@@ -534,7 +533,6 @@
-
!String methodsFor:'Compatibility-VW5.4'!
asByteString
@@ -1239,7 +1237,7 @@
'hello world' indexOfAny:'AOE' startingAt:1
'hello world' indexOfAny:'o' startingAt:6
'hello world' indexOfAny:'o' startingAt:6
- 'hello world§' indexOfAny:'#§$' startingAt:6
+ 'hello world§' indexOfAny:'#§$' startingAt:6
"
!
@@ -2471,22 +2469,6 @@
"
!
-asUUID
- "return self as a UUID"
-
- ^ UUID fromString:self
-
- "
- UUID genUUID asString asUUID
- '{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}' asUUID
- 'EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B' asUUID
- 'EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B quatsch' asUUID
- 'quark EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B' asUUID
- "
-
- "Modified: / 02-08-2007 / 16:43:29 / cg"
-!
-
beImmutable
"make myself write-protected"
@@ -3112,10 +3094,10 @@
'abcde1234' utf8EncodedOn:w
].
String streamContents:[:w|
- 'abcdeäöüß' utf8EncodedOn:w
+ 'abcdeäöüß' utf8EncodedOn:w
].
String streamContents:[:w|
- 'abcdeäöüß' asUnicode16String utf8EncodedOn:w
+ 'abcdeäöüß' asUnicode16String utf8EncodedOn:w
].
"
! !
@@ -3578,8 +3560,8 @@
"
'hello world' asUnicode16String errorPrint
(Character value:356) asString errorPrint
- 'Bönnigheim' errorPrint
- 'Bönnigheim' asUnicodeString errorPrint
+ 'Bönnigheim' errorPrint
+ 'Bönnigheim' asUnicodeString errorPrint
"
!
@@ -4507,3 +4489,4 @@
version_CVS
^ '$Header$'
! !
+