ビット演算子とは何ですか?
-
07-07-2019 - |
質問
私はただ趣味でコードを書いている人間で、学問や職業の場でコードを深く掘り下げたことはありません。そのため、これらのビット単位の演算子のようなものは本当に苦手です。
JavaScript に関する記事を読んでいましたが、JavaScript はビット単位の演算をサポートしているようです。この操作について言及されているのをあちこちで目にし、それが正確に何なのかを理解しようと読んでみましたが、まったく理解できないようです。それで、それらは何ですか?明確な例は素晴らしいでしょう!:D
さらにいくつか質問があります。ビット単位の演算の実際的な応用例は何ですか?いつ使用できますか?
解決
これらがなぜ役立つのかについては誰も議論していないため、次のようになります。
私はフラグを扱うときにビット単位の演算をよく使います。たとえば、一連のフラグを操作に渡したい場合 (たとえば、 File.Open()
, 、読み取りモードと書き込みモードの両方が有効になっている場合)、それらを単一の値として渡すことができます。これは、考えられる各フラグをビットセット内の独自のビット (バイト、ショート、整数、またはロング) に割り当てることによって実現されます。例えば:
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
と同じです
× * 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
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)
他のヒント
他の回答としてリストされている単一ビットの真理値表は、一度に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
各列の各ビットペアは、<!> quot; AND <!> quot;ボトムラインに対応する出力ビットを与える機能。したがって、上記の式の答えは4です。CPUは(この例では)8つの<!> quot; AND <!> quot;を実行しました。カラムごとに1つずつの並列操作。
これについて言及したのは、<!> quot; AHA!<!> quot;何年も前にこれについて学んだ瞬間。
ビットごとの演算子は、一度に少しずつ動作する演算子です。
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
これらはビット演算子であり、すべて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
-ZERO FILL
-<=>演算子はビットを右に移動し、右端のビットを破棄し、左端のビットに値0を割り当てます。右に移動するたびに効果的に分割されます半分のop1。左端の符号ビットは破棄されます。
もう少し詳しく説明すると、問題の値のバイナリ表現に関係があります。
For example (in decimal): x = 8 y = 1 would come out to (in binary): x = 1000 y = 0001 From there, you can do computational operations such as 'and' or 'or'; in this case: x | y = 1000 0001 | ------ 1001 or...9 in decimal
これが役立つことを願っています。
用語<!> quot; bitwise <!> quot;言及されているが、それは時々明確です!<!> quot; logical <!> quot;演算子。
たとえばJavaScriptの場合、ビット演算子はオペランドを32のシーケンスとして扱いますビット(ゼロと1);一方、通常、論理演算子はブール(論理)値で使用されます非ブール型で動作することができます。
expr1を取得<!> amp; <!> amp;たとえばexpr2。
expr1を変換できる場合はそれを返します falseに。それ以外の場合、expr2を返します。 したがって、ブール値を使用すると、 <!> amp; <!> amp;両方のオペランドが true;それ以外の場合はfalseを返します。
a = "Cat" && "Dog" // t && t returns Dog
a = 2 && 4 // t && t returns 4
他の人が述べたように、2 <!> amp; 4はビット単位のANDであるため、0を返します。
以下をtest.htmlまたは何かにコピーしてテストできます:
<html>
<body>
<script>
alert("\"Cat\" && \"Dog\" = " + ("Cat" && "Dog") + "\n"
+ "2 && 4 = " + (2 && 4) + "\n"
+ "2 & 4 = " + (2 & 4));
</script>
デジタルコンピュータープログラミングでは、ビット単位の操作は、1つまたは複数のビットパターンまたは個々のビットのレベルの2進数で行われます。これは、プロセッサによって直接サポートされる高速でプリミティブなアクションであり、比較や計算のために値を操作するために使用されます。
操作:
-
ビット単位AND
-
ビット単位のOR
-
ビット単位のNOT
-
ビット単位のXOR
-
etc
リストアイテム
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
- <!> amp;演算子を使用して、数値が奇数か偶数かをすばやく確認できます
例:
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番号でのみ機能します
また、ビットごとのロジックの幅広い使用
このように考えると役立つ場合があります。これがAND(<!> amp;)の仕組みです:
基本的に、これらは両方とも数字であると言われているため、5と3の数字が2つある場合、それらはバイナリに変換され、コンピューターは考えます
5: 00000101
3: 00000011
両方とも:00000001 0はfalse、1はtrue
したがって、5と3のANDは1です。 OR(|)演算子は同じことを行いますが、1を出力するには1つでなければならず、両方ではありません。
JavaScriptのビット単位の演算子がどれほど遅いかについて、私は聞き続けました。 私の最新のブログ投稿のテストを行い、いくつかのテストでは、算術的代替よりも40〜80%高速でした。おそらく彼らはかつては遅かったのでしょう。最新のブラウザでは、気に入っています。
コードにより、このために高速で読みやすいケースが1つあります。もっと目を開けておくよ。