私はビットについてもっと学ぼうとしていました、そして私はこの例に出くわしました。
このコードはビットをカウントするためにどのように機能しますか?(ちなみに、私のCはとても錆びています)。
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; v >>= 1)
{
c += v & 1;
}
私はビットについてもっと学ぼうとしていました、そして私はこの例に出くわしました。
このコードはビットをカウントするためにどのように機能しますか?(ちなみに、私のCはとても錆びています)。
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; v >>= 1)
{
c += v & 1;
}
v & 1
の最下位ビットv
が設定されている場合は1、そうでない場合は0です。
ループは、反復ごとに右のビットを1桁ずつシフトして分割し続けます。したがって、ループv
の最下位ビットは、元のビットの各ビットを超えます(各ビットが小数部の端から「落ちる」前に1の位に到達するため)。v
v
したがって、各ビットをループし、設定されている場合はcに1を追加し、設定されていない場合は0を追加して、元のvの設定ビットを合計します。
たとえば、次のように始まりv
ます1011
。
1011 & 1 = 1
、したがって、cは1にインクリメントされます。1011
、シフトしてになり101
ます。101 & 1 = 1
、したがって、cは2にインクリメントされます。101
にシフトされ10
ます。10 & 1 = 0
、したがって、cはインクリメントされず、2のままです。10
にシフトされ1
ます。1 & 1 = 1
、したがって、cは3にインクリメントされます。1
0
(最後のビットが小数端から落ちたため)になるようにシフトされます。for
はちょうどv
で、vは0になり、これはfalse値であるため、ループは停止します。最終結果、c = 3、必要に応じて。
v >> = 1は、vがすべてゼロになるまで最下位ビットをシフトし続けます。ですから、すべてを数えるまでやめません。v&1は、シフトオフしようとしているビットが1であるかどうかをテストするため、シフトオフする前に必ずカウントします。
v &
基本的に最下位ビットを抽出しますv
-1
そのビットが設定されている場合、0
そうでない場合です。ループを繰り返すたびv
に、1桁右にシフトします。そして、各反復内で、そのv &
テストの結果をカウンターに追加しc
ます。つまり、設定されているすべてのビット1
が追加されます。すべてのクリアビット0
が追加されます。
基本的に、1ビットをv
値1と比較しており、ANDの真理値表を知っています。
したがって、fromのビットv
が1の場合、1とAND演算すると1が生成されます。次にv
、1ビットシフトして続行します。