21

数値に設定されたビット数(ハミング重み)を与える次の魔法の公式。

/*Code to Calculate count of set bits in a number*/
int c;
int v = 7;
v = v - ((v >> 1) & 0x55555555);                    // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);     // temp
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count
printf(" Number of Bits is %d",c);
/*-----------------------------------*/

差出人:http : //graphics.stanford.edu/~seander/bithacks.html

誰かが私にこれの背後にある理論的根拠を説明できますか?

4

2 に答える 2

34

これは本当に非常に巧妙なコードであり、単純な単純なループよりも明らかに理解するのがはるかに困難です。

最初の行では、4ビットの量を取り、それを呼び出しましょうabcd。コードは基本的にこれを行います:

abcd - ((abcd >> 1) & 0101) = abcd - (0abc & 0101) = abcd - 0a0c

したがって、2ビットの各グループで、上位ビットの値を減算します。それは私たちに何をもたらしますか?

11 - 1 -> 10 (two bits set)
10 - 1 -> 01 (one bit set)
01 - 0 -> 01 (one bit set)
00 - 0 -> 00 (zero bits set)

したがって、その最初の行は、2ビットの連続する各グループを元の値に含まれるビット数に設定します。2つのグループに設定されたビットをカウントします。結果の4ビット量を呼び出しABCDます。

次の行:

(ABCD & 0011) + ((ABCD>>2) & 0011) = 00CD + (AB & 0011) = 00CD + 00AB

したがって、2ビットのグループを取り、ペアを追加します。これで、各4ビットグループには、入力の対応する4ビットに設定されたビット数が含まれます。

次の行v + (v >> 4) & 0xF0F0F0F(として解析される(v + (v >> 4)) & 0xf0f0f0f)も同じことを行い、4ビットグループのペアを追加して、各8ビットグループ(バイト)に対応する入力バイトのビットセットカウントが含まれるようにします。現在、のような番号があり0x0e0f0g0hます。

任意の位置のバイトにを掛けると、0x01010101そのバイトが最上位バイトにコピーされます(また、一部のコピーは下位バイトに残ります)。たとえば、0x00000g00 * 0x01010101 = 0x0g0g0g00。したがって、を乗算することにより、最上位バイト0x0e0f0g0hを残します。e+f+g+h最後に>>24そのバイトを抽出し、答えを残します。

于 2013-01-28T05:13:31.850 に答える
-2

与えられた2進数の1の数を数えるためのPythonの1つのライナーソリューション

[i for i in str(bin(n))if i == "1"]。count( "1")

于 2021-02-02T03:46:01.453 に答える