私はビットについてもっと学ぼうとしていました、そして私はこの例に出くわしました。
このコードはビットをカウントするためにどのように機能しますか?(ちなみに、私の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の位に到達するため)。vv
したがって、各ビットをループし、設定されている場合は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にインクリメントされます。10(最後のビットが小数端から落ちたため)になるようにシフトされます。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ビットシフトして続行します。