ネコさんとこのぱぱっと書かせるプログラムの問題、の続きで解説希望されたのでエントリ。回答自体はぱぱっと書かせるプログラムの問題のコメントに書いたんですが再掲します。
bool isAPo2(int num)
{
long bits = num;
bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
bits = (bits & 0x0000ffff) + (bits >> 16 & 0x0000ffff);
return (bits == 1);
}
一応マスクの形としては
0x55555555が01010101010101010101010101010101
0x33333333が00110011001100110011001100110011
0x0f0f0f0fが00001111000011110000111100001111
0x00ff00ffが00000000111111110000000011111111
0x0000ffffが00000000000000001111111111111111
やってることは立ってるビットを数えてそれが 1 なら 2 の乗数って判定をやってるだけ。
1bit と言うのはそれ自身で立ってる数と=になります。0 or 1 ね。
で、ここからがミソなんですが 2bit 毎に区切ってマスクしてやることでさっきと同じようにビットが立っているかどうかをあらわせます。
[N|T] こうね。で、Nの箇所も同様に判定するために右にずらしてから同じようにマスクこれで [T|N] Tに当たる箇所を取り出したことになります。右がわと左側ね。で、これらを足してやることで立っているビット数が [NN] として格納されるわけです。
あとはこれを同じように 4bit 毎、 8bit 毎とやっていくことで計算できます。
2bit は 1 回足せば OK 、 4bit なら 2 回足せば OK です。あとは順に増えるので 32bit なら 5 回で計算できることになります。
Savvy?<ちょと古い