3

たとえば、0110にはビット1と2が設定され、1000にはビット3が設定され、1111にはビット0、1、2、3が設定されます。

4

10 に答える 10

7

実際に4ビットしかない場合、最速の方法は確かにルックアップテーブルを必要とします。結局のところ、16の異なる可能性しかありません。

于 2008-09-16T02:51:53.370 に答える
6

これらすべてのビットハックに関するインターネットでの最良のリファレンス-ビットいじりハック

于 2008-09-16T03:15:16.730 に答える
4
for( int i = 0; variable ; ++i, variable >>= 1 ) {
  if( variable & 1 )
    // store bit index - i
}
于 2008-09-16T02:48:34.640 に答える
4

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

于 2008-09-16T02:42:17.353 に答える
1

それが .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 について話しているのですが、この場合も同じです。

于 2008-09-16T13:39:51.627 に答える
0

最速の意味によって異なります。

「コーディングが簡単」という意味の場合、.NETではBitArrayクラスを使用して、各ビットをブール値のtrue/falseとして参照できます。

BitArrayクラス

于 2008-09-16T02:50:16.447 に答える
0

@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.

于 2008-09-16T03:02:16.400 に答える
0

int のバイトを反復処理するハイブリッド アプローチを採用し、ルックアップ テーブルを使用して、各バイト (ニブルに分割) 内のセット ビットのインデックスを決定できます。次に、インデックスにオフセットを追加して、整数内の位置を反映する必要があります。

つまり、32 ビット int の MSB から始めたとします。上位ニブル インデックスを upper_idxs と呼び、下位ニブル インデックスを lower_idxs と呼びます。次に、lower_idxs の各要素に 24 を追加し、upper_idxs の各要素に 28 を追加する必要があります。次のバイトは、オフセットがそれぞれ 16 と 20 であることを除いて、同様に処理されます。これは、そのバイトが 8 ビット「下」であるためです。

私にはこのアプローチは合理的に思えますが、間違っていることを証明できれば幸いです:-)

于 2008-09-16T06:57:35.587 に答える
0

役立つと思います

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++;
        }
    }
}
于 2010-06-21T07:55:00.143 に答える
0

2 つのステップ:

  1. 設定された各ビットを抽出しますset_bit= x & -x; x&= x - 1;

  2. 1 を減算し、ビット セットをカウントします。

于 2008-09-16T23:34:11.183 に答える