134

私は楽しみのためにコードを書いているだけで、学術的または専門的な設定でコードを深く掘り下げていないので、これらのビット単位の演算子のようなものは本当に私を逃れます.

ビット単位の操作をサポートしているように見える JavaScript に関する記事を読んでいました。私はこの操作が所々で言及されているのを見続けており、それが正確に何であるかを理解するために約を読んでみましたが、まったく理解していないようです. それで、彼らは何ですか?明確な例は素晴らしいでしょう!:D

もう少し質問があります。ビット演算の実用的なアプリケーションにはどのようなものがありますか? いつそれらを使用できますか?

4

9 に答える 9

187

誰もこれらがなぜ有用であるかという主題を破ったことがないので:

フラグを操作するときは、ビット演算をよく使用します。たとえば、一連のフラグを操作に渡したい場合(たとえば、File.Open()読み取りモードと書き込みモードの両方が有効になっている場合)、それらを単一の値として渡すことができます。これは、可能な各フラグにビットセット内の独自のビット(byte、short、int、またはlong)を割り当てることによって実現されます。例えば:

 Read: 00000001
Write: 00000010

したがって、読み取りと書き込みを渡す場合は、(READ | WRITE)を渡すと、2つが次のように結合されます。

00000011

次に、次のようにもう一方の端で復号化できます。

if ((flag & Read) != 0) { //...

チェックする

00000011 &
00000001

これは

00000001

これは0ではないため、フラグはREADを指定します。

XORを使用して、さまざまなビットを切り替えることができます。フラグを使用して方向入力(上、下、左、右)を指定するときにこれを使用しました。たとえば、スプライトが水平方向に移動していて、向きを変えたい場合は、次のようにします。

     Up: 00000001
   Down: 00000010
   Left: 00000100
  Right: 00001000
Current: 00000100

現在の値を(LEFT | RIGHT)とXORするだけで、この場合はLEFTがオフになりRIGHTがオンになります。

ビットシフトはいくつかの場合に役立ちます。

x << y

と同じです

x * 2 y

2の累乗ですばやく乗算する必要があるが、1ビットを最上位ビットにシフトすることに注意する必要がある場合-これにより、符号なしでない限り、数値は負になります。さまざまなサイズのデータ​​を処理する場合にも役立ちます。たとえば、4バイトから整数を読み取る場合:

int val = (A << 24) | (B << 16) | (C << 8) | D;

Aが最上位バイトで、Dが最下位であると仮定します。最終的には次のようになります。

A = 01000000
B = 00000101
C = 00101011
D = 11100011
val = 01000000 00000101 00101011 11100011

多くの場合、色は次のように保存されます(最上位バイトは無視されるか、アルファとして使用されます)。

A = 255 = 11111111
R = 21 = 00010101
G = 255 = 11111111
B = 0 = 00000000
Color = 11111111 00010101 11111111 00000000

値を再度見つけるには、ビットを右にシフトして一番下になるようにしてから、残りの上位ビットをマスクします。

Int Alpha = Color >> 24
Int Red = Color >> 16 & 0xFF
Int Green = Color >> 8 & 0xFF
Int Blue = Color & 0xFF

0xFFと同じ11111111です。つまり、基本的に、Redの場合、次のようになります。

Color >> 16 = (filled in 00000000 00000000)11111111 00010101  (removed 11111111 00000000)
00000000 00000000 11111111 00010101 &
00000000 00000000 00000000 11111111 =
00000000 00000000 00000000 00010101 (The original value)
于 2008-11-10T00:39:20.750 に答える
29

他の回答としてリストされている単一ビットの真理値表は、一度に 1 つまたは 2 つの入力ビットに対してのみ機能することに注意してください。次のような整数を使用するとどうなりますか。

int x = 5 & 6;

答えは、各入力のバイナリ展開にあります。

  5 = 0 0 0 0 0 1 0 1
& 6 = 0 0 0 0 0 1 1 0
---------------------
      0 0 0 0 0 1 0 0

各列のビットの各ペアは「AND」関数を介して実行され、対応する出力ビットが最下行に表示されます。したがって、上記の式の答えは 4 です。CPU は (この例では) 8 つの個別の "AND" 演算を並列に実行しました。各列に 1 つずつです。

この「AHA!」があったことを今でも覚えているので、これについて言及します。何年も前にこれを知った瞬間。

于 2008-11-10T00:11:05.223 に答える
28

ビット演算子は、一度に少しずつ処理する演算子です。

AND は、両方の入力が 1 の場合にのみ 1 になります。

1 つ以上の入力が 1 の場合、OR は 1 です。

XOR は、その入力の 1 つだけが 1 の場合にのみ 1 です。

NOT は、入力が 0 の場合にのみ 1 になります。

これらは、真理値表として最もよく説明できます。入力の可能性は上部と左側にあり、結果のビットは、2 つの入力の交点に示される 4 つの値 (入力が 1 つしかないため、NOT の場合は 2 つ) の 1 つです。

AND|0 1      OR|0 1
---+----    ---+----
  0|0 0       0|0 1
  1|0 1       1|1 1

XOR|0 1     NOT|0 1
---+----    ---+---
  0|0 1        |1 0
  1|1 0

1 つの例として、整数の下位 4 ビットのみが必要な場合は、15 (バイナリ 1111) と AND します。

    203: 1100 1011
AND  15: 0000 1111
------------------
 IS  11: 0000 1011
于 2008-11-10T00:04:28.373 に答える
17

これらはビットごとの演算子で、すべて JavaScript でサポートされています。

  • op1 & op2--AND演算子は 2 つのビットを比較し、両方のビットが 1 の場合は 1 の結果を生成します。それ以外の場合は 0 を返します。

  • op1 | op2--OR演算子は 2 つのビットを比較し、ビットが相補的である場合は 1 の結果を生成します。それ以外の場合は 0 を返します。

  • op1 ^ op2-- このEXCLUSIVE-OR演算子は 2 つのビットを比較し、いずれかのビットが 1 の場合は 1 を返し、両方のビットが 0 または 1 の場合は 0 を返します。

  • ~op1--COMPLEMENT演算子は、オペランドのすべてのビットを反転するために使用されます。

  • op1 << op2--SHIFT LEFT演算子はビットを左に移動し、左端のビットを破棄し、右端のビットに値 0 を割り当てます。左に移動するたびに、実質的に op1 に 2 が乗算されます。

  • op1 >> op2--SHIFT RIGHT演算子はビットを右に移動し、右端のビットを破棄し、左端のビットに値 0 を割り当てます。右に移動するたびに、op1 は事実上半分に分割されます。一番左の符号ビットは保持されます。

  • op1 >>> op2--演算子SHIFT RIGHT-ZERO FILLはビットを右に移動し、右端のビットを破棄し、左端のビットに値 0 を割り当てます。右に移動するたびに、op1 は事実上半分に分割されます。一番左の符号ビットは破棄されます。

于 2008-11-10T00:03:13.273 に答える
4

「ビット単位」という用語が言及されている場合、それが「論理」演算子ではないことが明確になることがあります。

たとえば、JavaScriptでは、ビット演算子はオペランドを32ビット(0と1)のシーケンスとして扱います。一方、論理演算子は通常、ブール(論理)値で使用されますが、非ブール型でも機能します。

expr1&&expr2を例にとってみましょう。

falseに変換できる場合はexpr1を返します。それ以外の場合は、expr2を返します。したがって、ブール値とともに使用すると、&&は両方のオペランドがtrueの場合にtrueを返します。それ以外の場合は、falseを返します。

a = "Cat" && "Dog"     // t && t returns Dog
a = 2 && 4     // t && t returns 4

他の人が指摘しているように、2と4はビット単位のANDであるため、0を返します。

以下をtest.htmlなどにコピーしてテストできます。

<html>
<body>
<script>
    alert("\"Cat\" && \"Dog\" = " + ("Cat" && "Dog") + "\n"
        + "2 && 4 = " + (2 && 4) + "\n"
        + "2 & 4 = " + (2 & 4));
</script>
于 2008-11-10T00:26:02.040 に答える
4

デジタル コンピューター プログラミングでは、ビットごとの演算は、1 つまたは複数のビット パターンまたは 2 進数に対して、個々のビットのレベルで動作します。これは、プロセッサによって直接サポートされる高速でプリミティブなアクションであり、比較と計算のために値を操作するために使用されます。

操作:

  • ビットごとの AND

  • ビットごとの OR

  • ビット単位の NOT

  • ビット単位の XOR

リスト項目

    AND|0 1        OR|0 1 
    ---+----      ---+---- 
      0|0 0         0|0 1 
      1|0 1         1|1 1 

   XOR|0 1        NOT|0 1 
   ---+----       ---+--- 
     0|0 1           |1 0 
     1|1 0

例えば。

    203: 1100 1011
AND  15: 0000 1111
------------------
  =  11: 0000 1011

ビット演算子の使用

  • 左シフト演算子と右シフト演算子は、それぞれ x * 2 yによる乗算と除算に相当します。

例えば。

int main()
{
     int x = 19;
     printf ("x << 1 = %d\n" , x <<1);
     printf ("x >> 1 = %d\n", x >>1);
     return 0;
}
// Output: 38 9
  • & 演算子を使用すると、数値が奇数か偶数かをすばやく確認できます

例えば。

int main()
{
    int x = 19;
    (x & 1)? printf("Odd"): printf("Even");
    return 0;
 }
// Output: Odd
  • if elseステートメントなしで x と y の最小値をすばやく見つける

例えば。

int min(int x, int y)
{
    return y ^ ((x ^ y) & - (x < y))
}
  • 10 進数から 2 進数への変換

例えば。

#include <stdio.h>
int main ()
{
    int n , c , k ;
    printf("Enter an integer in decimal number system\n " ) ;
    scanf( "%d" , & n );
    printf("%d in binary number
    system is: \n " , n ) ;
    for ( c = 31; c >= 0 ; c -- )
    {
         k = n >> c ;
         if ( k & 1 )
              printf("1" ) ;
         else
              printf("0" ) ;
      }
      printf(" \n " );
      return 0 ;
}
  • XOR ゲート暗号化は、その複雑さとプログラマーによる使用の難しさから、人気のある手法です。
  • ビット単位の XOR 演算子は、技術面接の観点から最も有用な演算子です。

ビット単位のシフトは +ve 番号でのみ機能します

また、ビットごとのロジックの幅広い用途があります

于 2016-04-21T07:02:19.427 に答える
4

もう少し詳しく説明すると、問題の値のバイナリ表現に大きく関係しています。

例 (10 進数):
x = 8
y = 1

(バイナリで)に出てきます:
x = 1000
y = 0001

そこから、「and」や「or」などの計算操作を実行できます。この場合:
× | y =
1000
0001 |
------
1001

または...10進数で9

お役に立てれば。

于 2008-11-10T00:14:43.203 に答える
-5

JavaScript のビット演算子がいかに遅いかという話をよく耳にしました。最新のブログ投稿のためにいくつかのテストを行ったところ、いくつかのテストで算術の代替手段よりも 40% から 80% 高速であることがわかりました。おそらく、彼らはかつては遅かったのでしょう。最新のブラウザーでは、私はそれらが大好きです。

これにより、私のコードには、より速く、より読みやすくなるケースが 1 つあります。私はもっ​​と目を開いたままにします。

于 2009-02-10T00:35:44.707 に答える