web-dev-qa-db-ja.com

ビット演算子とは何ですか?

私は楽しみのためだけにコードを書いており、アカデミックな環境でもプロの環境でもコードを詳しく調べていないので、これらのビット演算子のようなものは本当に私を逃れます。

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

もう少し質問-ビット演算の実用的なアプリケーションは何ですか?いつそれらを使用しますか?

124
click

なぜこれらが有用なのかという主題を誰も紹介していないので:

フラグを操作するとき、ビット単位の操作を頻繁に使用します。たとえば、一連のフラグを操作に渡す場合(たとえば、読み取りモードと書き込みモードの両方を有効にした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

私は単純にXOR(LEFT | RIGHT)で現在の値を返します。この場合、LEFTをオフにし、RIGHTをオンにします。

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

x << y

と同じです

x * 2y

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

0xFF11111111と同じです。本質的に、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)
181
Ed Marty

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

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
27
paxdiablo

他の回答としてリストされている単一ビットの真理値表は、一度に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は(この例では)各列に1つずつ、8つの「AND」演算を並列に実行しました。

私はまだこの「AHA!」を覚えているからです。何年も前にこのことを知った瞬間。

27
Greg Hewgill

これらはビット単位の演算子であり、すべて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は事実上半分に分割されます。左端の符号ビットは破棄されます。

15
Jeff Hillman

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

たとえば、JavaScriptの場合、 ビットごとの演算子は、オペランドを32ビットのシーケンス(ゼロと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>
4
Eugene Yokota

もう少し詳しく説明すると、問題の値のバイナリ表現に関係があります。

たとえば(10進数):
 x = 8 
 y = 1 
 
は(バイナリで):
 x = 1000 
 y = 0001 
 
そこから、「and」や「or」などの計算操作を実行できます。この場合:
 x | y = 
 1000 
 0001 | 
 ------ 
 1001 
 
または... 10進数で9 

お役に立てれば。

4
javamonkey79

デジタルコンピュータプログラミングでは、ビットごとの操作は、それらの個々のビットのレベルで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ゲート暗号化は、プログラマーによる複雑さと再利用のため、一般的な手法です。
    • bitwise XOR演算子は技術面接の観点から最も有用な演算子です。

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

ビットごとの論理の幅広い使用法もあります

3
Prashant Kumar

このように考えると役立つかもしれません。これがAND(&)の仕組みです:

基本的にこれらは両方とも数字だと言うので、5と3の数字が2つある場合、それらはバイナリに変換され、コンピューターは

         5: 00000101
         3: 00000011

両方とも:00000001 0は偽、1は真

したがって、5と3のANDは1です。 OR(|)演算子は同じことを行いますが、1を出力するには1つだけで、両方ではない必要があります。

1
user3677963