たとえば、0110にはビット1と2が設定され、1000にはビット3が設定され、1111にはビット0、1、2、3が設定されます。
10 に答える
実際に4ビットしかない場合、最速の方法は確かにルックアップテーブルを必要とします。結局のところ、16の異なる可能性しかありません。
これらすべてのビットハックに関するインターネットでの最良のリファレンス-ビットいじりハック
for( int i = 0; variable ; ++i, variable >>= 1 ) {
if( variable & 1 )
// store bit index - i
}
I would shift it down and test the least significant bit in a loop. It might be faster testing with 32 bit masks (or whatever length your unsigned int is).
/Allan
それが .NET であり、頻繁に使用する必要がある場合は、流暢なインターフェイスが必要です。
次のクラスを作成します (BitTools という名前には完全に満足していません)。
[Flags]
public enum Int32Bits
{
// Lookup table but nicer
None = 0,
Bit1 = 1, Bit2 = 1 << 1, Bit3 = 1 << 2, Bit4 = 1 << 3, Bit5 = 1 << 4, Bit6 = 1 << 5, Bit7 = 1 << 6, Bit8 = 1 << 7,
Bit9 = 1 << 8, Bit10 = 1 << 9, Bit11 = 1 << 10, Bit12 = 1 << 11, Bit13 = 1 << 12, Bit14 = 1 << 13, Bit15 = 1 << 14, Bit16 = 1 << 15,
Bit17 = 1 << 16, Bit18 = 1 << 17, Bit19 = 1 << 18, Bit20 = 1 << 19, Bit21 = 1 << 20, Bit22 = 1 << 21, Bit23 = 1 << 22, Bit24 = 1 << 23,
Bit25 = 1 << 24, Bit26 = 1 << 25, Bit27 = 1 << 26, Bit28 = 1 << 27, Bit29 = 1 << 28, Bit30 = 1 << 29, Bit31 = 1 << 30, Bit32 = 1 << 31,
}
public static class BitTools
{
public static Boolean IsSet(Int32 value, Int32Bits bitToCheck)
{
return ((Int32Bits)value & bitToCheck) == bitToCheck;
}
public static Boolean IsSet(UInt32 value, Int32Bits bitToCheck)
{
return ((Int32Bits)value & bitToCheck) == bitToCheck;
}
public static Boolean IsBitSet(this Int32 value, Int32Bits bitToCheck)
{
return ((Int32Bits)value & bitToCheck) == bitToCheck;
}
public static Boolean IsBitSet(this UInt32 value, Int32Bits bitToCheck)
{
return ((Int32Bits)value & bitToCheck) == bitToCheck;
}
}
そして、次の方法で使用できます。
static void Main(string[] args)
{
UInt32 testValue = 5557; //1010110110101;
if (BitTools.IsSet(testValue, Int32Bits.Bit1))
{
Console.WriteLine("The first bit is set!");
}
if (testValue.IsBitSet(Int32Bits.Bit5))
{
Console.WriteLine("The fifth bit is set!");
}
if (!testValue.IsBitSet(Int32Bits.Bit2))
{
Console.WriteLine("The second bit is NOT set!");
}
}
(U)Int サイズごとに、別の Int*Bits 列挙型と、IsSet および IsBitSet の正しいオーバーロードを作成できます。
編集: 読み間違えましたが、unsigned int について話しているのですが、この場合も同じです。
最速の意味によって異なります。
「コーディングが簡単」という意味の場合、.NETではBitArrayクラスを使用して、各ビットをブール値のtrue/falseとして参照できます。
@Allan Wind...
The extra bit shifts are not needed. It is more efficient to not do a bit shift, as comparing the least significant bit is just as efficient as comparing the 2nd least significant bit, and so on. Doing a bit shift as well is just doubling the bit operations needed.
firstbit = (x & 0x00000001)
secondbit = (x & 0x00000002)
thirdbit = (x & 0x00000004) //<-- I'm not saying to store these values, just giving an example.
...
All operations on an x86 system anyway are done with 32-bit registers, so a single bit compare would be just as efficient as a 32-bit compare.
Not to mention the overhead of having the loop itself.
The problem can be done in a constant number of lines of code and whether the code is run on an x86 or an x64, the way I describe is more efficient.
int のバイトを反復処理するハイブリッド アプローチを採用し、ルックアップ テーブルを使用して、各バイト (ニブルに分割) 内のセット ビットのインデックスを決定できます。次に、インデックスにオフセットを追加して、整数内の位置を反映する必要があります。
つまり、32 ビット int の MSB から始めたとします。上位ニブル インデックスを upper_idxs と呼び、下位ニブル インデックスを lower_idxs と呼びます。次に、lower_idxs の各要素に 24 を追加し、upper_idxs の各要素に 28 を追加する必要があります。次のバイトは、オフセットがそれぞれ 16 と 20 であることを除いて、同様に処理されます。これは、そのバイトが 8 ビット「下」であるためです。
私にはこのアプローチは合理的に思えますが、間違っていることを証明できれば幸いです:-)
役立つと思います
import java.util.*;
public class bitSet {
public static void main(String[]args) {
Scanner scnr = new Scanner(System.in);
int x = scnr.nextInt();
int i = 0;
while (i<32) {
if ( ((x>>i)&1) == 1) {
System.out.println(i);
}
i++;
}
}
}
2 つのステップ:
設定された各ビットを抽出します
set_bit= x & -x; x&= x - 1;
1 を減算し、ビット セットをカウントします。