挑战位操作过程
这个问题出现在我老师的一次老考试中。 人们如何才能逻辑思考得出答案?
我熟悉位操作符和十六进制和二进制之间的转换。
int whatisthis(int x) {
x = (0x55555555 & x) + (0x55555555 & (x >>> 1));
x = (0x33333333 & x) + (0x33333333 & (x >>> 2));
x = (0x0f0f0f0f & x) + (0x0f0f0f0f & (x >>> 4));
x = (0x00ff00ff & x) + (0x00ff00ff & (x >>> 8));
x = (0x0000ffff & x) + (0x0000ffff & (x >>> 16));
return x;
}
你不忘记一些左派班吗?
x = ((0x55555555 & x) <<< 1) + (0x55555555 & (x >>> 1));
x = ((0x33333333 & x) <<< 2) + (0x33333333 & (x >>> 2));
snip...
这将是从左到右的位反转。
你可以看到比特被一起移动而不是逐个移动,这导致O(log2(nbit))的代价
(你在5个语句中反转2 ^ 5 = 32位)
它可以帮助你用二进制重写常量以更好地理解它的工作原理。
如果没有左移,那么我不能帮助你,因为这些增加会产生进位,我看不到任何明显的含义......
编辑 :好的,有趣的,所以这是用于计数设置为1的位数(也称为总体数量或popcount)...这是一个吱吱叫的Smalltalk 16位快速测试
| f |
f := [:x |
| y |
y := (x bitAnd: 16r5555) + (x >> 1 bitAnd: 16r5555).
y := (y bitAnd: 16r3333) + (y >> 2 bitAnd: 16r3333).
y := (y bitAnd: 16r0F0F) + (y >> 4 bitAnd: 16r0F0F).
y := (y bitAnd: 16r00FF) + (y >> 8 bitAnd: 16r00FF).
y].
^(0 to: 16rFFFF) detect: [:i | i bitCount ~= (f value: i)] ifNone: [nil]
第一个语句处理每个位对。 如果该对未设置位,则它产生00,如果设置了一位,则产生01,如果设置了两位,则产生10。
00 -> 0+0 -> 00 = 0, no bit set
01 -> 1+0 -> 01 = 1, 1 bit set
10 -> 0+1 -> 01 = 1, 1 bit set
11 -> 1+1 -> 10 = 2, 2 bits set
所以它计算每对中的位数。
第二个语句处理4个相邻位的组:
0000 -> 00+00 -> 0000 0+0=0 bits set
0001 -> 01+00 -> 0001 1+0=1 bits set
0010 -> 10+00 -> 0010 2+0=2 bits set
0100 -> 00+01 -> 0001 0+1=1 bits set
0101 -> 01+01 -> 0010 1+1=2 bits set
0110 -> 10+01 -> 0011 2+1=3 bits set
1000 -> 00+10 -> 0010 0+2=2 bits set
1001 -> 01+10 -> 0011 1+2=3 bits set
1010 -> 10+10 -> 0100 2+2=4 bits set
所以,虽然第一步没有用这一对中设置的位数替换每对位,但第二步确实在每对中加了这个计数......
接下来将处理每组8个相邻比特,并且将两组比特数集合成4组......
链接地址: http://www.djcxy.com/p/36395.html