7

私は次のような5ビットの数字を持っています

10000
01000
00100

私の計算で1ビットだけがオンになっている場合、問題はありません。

しかし、2ビットがオンの場合、たとえば最初のオンビットのみを選択したい

10010

数字の18ではなく2として扱いたい

そのような状況で使用できるビット単位の操作はありますか?

4

4 に答える 4

35

インデックスを取得するのではなく、分離するだけなので、簡単です。

function firstSetBit(number)
{
    return number & -number;
}

-numberこれは、「2の補数」と呼ばれるのバイナリ表現のために機能します。

0000001101111000より良い例を得るために、数値が2進数の888であるとしましょう。先行ゼロは16ビットの数値になりますが、これは任意の整数サイズで機能します。

数値の2の補数を取得するには、最初にそれを補数として、すべての1を0に、0を1に設定します。

          number: 0000001101111000
      complement: 1111110010000111

次に、それに1を追加します。

          number: 0000001101111000
      complement: 1111110010000111
           add 1: 1111110010001000

右端のビットが1の場合、これによりキャリーが作成され、0に達するまですべての1が0に反転することに注意してください。

この数値は、実際にはの2進表現でもあり-numberます。

          number: 0000001101111000
      complement: 1111110010000111
           add 1: 1111110010001000
         -number: 1111110010001000

ここで、ビット単位の&ofnumberとを取り-numberます。

          number: 0000001101111000
         -number: 1111110010001000
number & -number: 0000000000001000

ターゲットビットの右側には、number前提としてすべて0があります。-numberまた、+ 1の間に反転したため、すべて0です。0と0のビットごとのANDは、0を生成します。

ターゲットビットにnumberは、これも前提として1があります。-numberまた、否定が0に変換され、1に戻されるため、1があります。1と1のビットごとのANDは、1を生成します。

ターゲットビットの左側にあり、2の補数手順の+1ステップによって影響を受けないためnumber、常に0と1のペアを形成します。-number1と0のビットごとのANDは、0を生成します。

したがって、number & -number数値の最下位1ビットを生成することを示しました。

于 2012-09-03T15:54:17.380 に答える
-3
function isolateLowestBit(input)
{
  mask = 1;
  while (mask <= input)
  {
    if (mask & input)
    {
      // found match - mask is set to the value of the lowest bit
      return mask;
    }

    mask *= 2;  // shift up mask by one bit
  }

  // no match
  return 0;
}

Javascriptの数値は自然に整数ではないため、Javascriptでのビット演算はお勧めできません。

于 2012-09-03T12:13:38.063 に答える
-3

二項演算子は通常、数値のすべてのビットに影響します。そのため、数字の最初の「1」だけを取得する特別な関数はありません。しかし、そのような機能を試すことができます:

function filterFirstFoundBit(number)
{
    for (var i = 0; i < 32; i++) {
        if ((1 << i) & number)
        {
            return 1 << i;
        }
    }
    return number;
}
document.write(filterFirstFoundBit(9)); //10010​​​​​​​​

ここで試してみてください

于 2012-09-03T11:58:12.830 に答える