# HG changeset patch # User Claus Gittinger # Date 1369642102 -7200 # Node ID 986b2cc65f2ee7a030ca7523aabbb0215d5086d6 # Parent 2e79d57ea5ca317a0b66412a6fa817f001573f95 class: SmallInteger changed: #bitCount #intlog10 #swapBytes 64bit fixes diff -r 2e79d57ea5ca -r 986b2cc65f2e SmallInteger.st --- a/SmallInteger.st Fri May 24 20:14:44 2013 +0200 +++ b/SmallInteger.st Mon May 27 10:08:22 2013 +0200 @@ -808,6 +808,7 @@ ! ! + !SmallInteger methodsFor:'bit operators'! bitAnd:anInteger @@ -906,31 +907,31 @@ unsigned int _cnt; unsigned INT _self = __intVal(self); -#define ALGORIHTM_3 - -#ifdef ALGORITHM_1 +# define ALGORIHTM_3 + +# ifdef ALGORITHM_1 // old k&r code; might be better if only one or two bits are set _cnt = 0; while (_self) { - _cnt++; - _self = _self & (_self - 1); + _cnt++; + _self = _self & (_self - 1); } -#else -# ifdef ALGORITHM_2 +# 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 }; _cnt = 0; while (_self) { - _cnt += table[ _self & 0x0F ]; - _self >>= 4; + _cnt += table[ _self & 0x0F ]; + _self >>= 4; } -# else -# ifdef ALGORIHTM_3 +# else +# ifdef ALGORIHTM_3 // the fastest, but hard (impossible) to understand (google for fastest bit count) -# if __POINTER_SIZE__ == 8 +# if __POINTER_SIZE__ == 8 unsigned int _v1, _v2; _v1 = _self & 0xFFFFFFFF; @@ -944,42 +945,43 @@ _v2 = ((_v2 + (_v2 >> 4)) & 0x0F0F0F0F); _cnt = ((_v1 * 0x01010101) >> 24) + ((_v2 * 0x01010101) >> 24); -# else +# else _cnt = _self - ((_self >> 1) & 0x55555555); _cnt = (_cnt & 0x33333333) + ((_cnt >> 2) & 0x33333333); _cnt = ((_cnt + (_cnt >> 4)) & 0x0F0F0F0F); _cnt = (_cnt * 0x01010101) >> 24; +# endif +# else + error error error # endif -# else - error error error # endif # endif -#endif RETURN ( __MKSMALLINT(_cnt)); %} " + 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 + 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 ) 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) ] " @@ -2114,19 +2116,25 @@ %{ /* NOCONTEXT */ -#if __POINTER_SIZE__ == 4 - unsigned int v = __intVal(self); - unsigned int swapped; - - swapped = ((v&0xFF000000)>>8) | ((v&0xFF0000) << 8) | ((v & 0xFF00)>>8) | ((v & 0xFF)<<8); + unsigned INT v = __intVal(self); + unsigned INT swapped; + +#if __POINTER_SIZE__ == 8 + swapped = ((v&0xFF00FF00FF00FF00)>>8) | ((v&0x00FF00FF00FF00FF) << 8); +#else + swapped = ((v&0xFF00FF00)>>8) | ((v&0x00FF00FF) << 8); +#endif /* __POINTER_SIZE__ */ + if (__ISVALIDINTEGER(swapped)) { + RETURN ( __mkSmallInteger(swapped) ); + } RETURN (__MKUINT(swapped)); -#endif /* __POINTER_SIZE__ */ %}. ^ super swapBytes " 16r11223344 swapBytes hexPrintString 16r44332211 swapBytes hexPrintString + 16r1122 swapBytes hexPrintString " "Created: / 09-01-2012 / 23:01:33 / cg" @@ -3393,28 +3401,42 @@ (i.e. without log)." self <= 0 ifTrue:[ - ^ self class - raise:#domainErrorSignal - receiver:self - selector:#intlog10 - arguments:#() - errorString:'logarithm of negative integer' + ^ self class + raise:#domainErrorSignal + receiver:self + selector:#intlog10 + arguments:#() + errorString:'logarithm of negative integer' ]. self < 10000 ifTrue:[ - self < 10 ifTrue:[^ 0]. - self < 100 ifTrue:[^ 1]. - self < 1000 ifTrue:[^ 2]. - ^ 3 + self < 10 ifTrue:[^ 0]. + self < 100 ifTrue:[^ 1]. + self < 1000 ifTrue:[^ 2]. + ^ 3 ]. self < 100000000 ifTrue:[ - self < 100000 ifTrue:[^ 4]. - self < 1000000 ifTrue:[^ 5]. - self < 10000000 ifTrue:[^ 6]. - ^ 7 + self < 100000 ifTrue:[^ 4]. + self < 1000000 ifTrue:[^ 5]. + self < 10000000 ifTrue:[^ 6]. + ^ 7 ]. self < 1000000000 ifTrue:[^ 8]. - ^ 9 - + + SmallInteger maxBytes == 4 ifTrue:[ + ^ 9 + ] ifFalse:[ + self < 10000000000 ifTrue:[^ 9]. + self < 100000000000 ifTrue:[^ 10]. + self < 1000000000000 ifTrue:[^ 11]. + self < 10000000000000 ifTrue:[^ 12]. + self < 100000000000000 ifTrue:[^ 13]. + self < 1000000000000000 ifTrue:[^ 14]. + self < 10000000000000000 ifTrue:[^ 15]. + self < 100000000000000000 ifTrue:[^ 16]. + self < 1000000000000000000 ifTrue:[^ 17]. + ^ 18. + ]. + "/ not reached " 99 intlog10 100 intlog10 @@ -4199,11 +4221,11 @@ !SmallInteger class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.205 2013-05-21 20:17:58 cg Exp $' + ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.206 2013-05-27 08:08:22 cg Exp $' ! version_CVS - ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.205 2013-05-21 20:17:58 cg Exp $' + ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.206 2013-05-27 08:08:22 cg Exp $' ! !