ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript のビット演算子

JavaScript のビット演算子

伊谢尔伦
伊谢尔伦オリジナル
2016-11-22 14:03:481764ブラウズ

JavaScript には &、|、^、~、<<、>>、>>> という 7 つのビット演算子があります (C# にはこの演算子はありませんが、C# には > > を渡すことができます)。この演算を実装するには論理右シフト)、ビット演算はすべてバイナリで実行されます。

ビット単位の AND 演算子 (&)

2 つの数値の同じビットが両方とも 1 の場合は 1 を返し、それ以外の場合は 0 を返します。たとえば、1&2=0、1 のバイナリ表現は 0001、2 のバイナリ表現は 0010 です。 、両方 この操作は 0000 を返します。

ビット単位の OR 演算子 (|)

2 つの数値が同じ桁で異なる場合は 1 を返し、そうでない場合は 0 (1|2=3 など) を返します。

ビットごとの XOR 演算子 (^)

2 つの数値が同じビットを持ち、1 つだけが 1 の場合は 1 を返し、それ以外の場合は 0 を返します (例: 1^2=3)。

ビット単位の NOT 演算子 (~)

~ は、すべてのビットを否定する単項演算子です。まず、負の数の格納について説明する必要があります。負の数は、正の数の 2 の補数で格納されます。したがって、負の数に対して演算を実行するときは、そのバイナリ エンコーディング、つまり 2 の値を正しく取得する必要があります。正の数のコードの補数。補数は 1 を反転して加算することで実現されます。以下の例を見てみましょう:

まず 3 の補数を計算します: 3 のバイナリ形式は 00000011、その補数は 11111100、その補数は 11111101 です。したがって、バイナリ コードは-3 の補数は 11111101 である場合、~-3 が必要です。これは、その補数である 00000010 を取得するためのものです。これは -3 の補数であり、10 進数の 2 に変換されます。

さらに数回試してみると、数値の補数は実際にはその小数の反対から 1 を引いたものであることがわかります。

左シフト演算子 (<<)

左シフト演算子は、最初のビットが 2 番目のビットになり、2 番目のビットが 3 番目のビットになるように、数値のすべてのビットをまとめて左にシフトします。 。 。空になった新しいビットは 0 で埋められます。たとえば、 1 < の 2 進表現は 1111 1111 です。これを 2 桁左に移動すると、1111 1100 になります。1 で始まる数値は負の数値です。これを 10 進数に変換するには、逆方向の補数計算を実行する必要があります。つまり、最初に 1 を引いて 1111 1011 を取得し、次にそれを否定して 0000 0100 を取得し、それを 10 進数に変換し、負符号を追加して 4 を取得します。ここで、バイナリ減算アルゴリズムに注意する必要があります: 1-1=0-0=0、1-0=1、0-1=1 (上位ビットから借用)。

ここで、左シフト演算は 10 進数に 2 の累乗を乗算することであることがわかります。

符号付き右シフト演算子 (>>)

左シフトは 2 で乗算されるため、右シフトは 2 で除算する必要があります。実際、数値自体が正の数値の場合、これが当てはまります。次に、上位ビットに 0 を加算し、負の数の場合は上位ビットに 1 を加算します。たとえば、3 > エンコーディングは 1111 1101 です。これを 1 ビット右に移動すると、1111 1110 になります。これは負の数です。まず、1 を引いて 1111 1101 を取得します。これを反転すると、0000 になります。 0010 を入力すると -2 になります。

符号付き右シフト演算は、10 進数を 2 の累乗で割って余りを破棄することです。

符号なし右シフト演算子 (>>>)

正の数の符号なし右シフト演算の結果は、符号付きの右シフト演算 (主に負の数の符号なし右シフト演算) と同じです。符号付き右シフトとの違いは、正の数であっても負の数であっても、上位ビットに 0 が追加されるため、正の数の場合、符号付きと符号なしの演算は同じですが、負の数の場合は次のようになります。違いの世界。例: -1 > 1111 1111 1111 1111 1111 1111 1111、最初の桁は 0 で、10 進数に変換すると 230+229+...+20=230(1-1/231) となります。 /(1-1/2)=231 -1=2147483647 したがって、最終的に必要な結果が得られました。結果はひどいものです。使用には注意してください。

ビットごとの演算子の応用:

長く話してきましたが、最終的な目標は、これらの演算子を使用することです。いくつかの例を見てみましょう:

色の RGB 値と 16 進数の変換: たとえば、色の値: # 33cc10、最初の 2 桁は赤 (R)、真ん中の 2 桁は緑 (G)、最後の 2 桁は青 (B) を表します。0011 0011 1100 1100 0001 0000 (色に割り当て) となります。まず赤色の値を取得したいので、それを右に 16 ビットシフトする必要があります (color>>16、つまり 0000 0000 0000 0000 0011 0011)。このようにして R=51 を取得します。最初にシフトする必要がある緑色の値を取得します。 color>>8 で右に 8 ビットシフトして 0000 0000 0011 0011 1100 1100 を取得し、最初の 8 ビットを 0, 0000 0000 0011 0011 1100 1100|0000 0000 に変更します。 0000 0000 1111 1111、0000 0 000 0000 0000 1100 1100 を取得します。このようにして G=204 を取得し、最後に青色の値を取得します。これは、最初の 8 桁を 0 に変更するだけです。 color | 0000 0000 0000 0000 0001 0000 の場合、B=16 が得られ、#33cc10 を RGB 値に変換すると (51,204 ,16) になります。一方、RGB を 16 進数に変換する方法は、G

ノードが別のノードの親ノードであるかどうかを判断する: たとえば、2 つのノード a と b があるとします。ie のメソッドは、a が b の子ノードであるかどうかを判断するのに対し、他の最新のブラウザーは a.contains(b) を使用します。 a.compareDocumentPosition(b) メソッドを使用します。この戻り結果はブール値ではありません。a と b が同じノードの場合は、0 を返します。a と b が異なるドキュメント内にあるか、少なくとも 1 つが外部にある場合は、0 を返します。 b が a より前にある場合は 2 が返され、a が b より前にある場合は 4 が返され、b に a が含まれている場合は 8 が返され、a に b が含まれている場合は 16 が返され、32 は文書に排他的です。ブラウザ。 0、1、2、4、8、16のバイナリコードはそれぞれ0000 0000、0000 0001、0000 0010、0000 0100、0000 1000、0001 0000です。a.compareDocumentPosition(b)を判定することでブール値に変換できます。 & 16 true または false で a が b のノードであるかどうかを判断するには、 a.compareDocumentPosition(b) == 16 を使用して判断しないのはなぜでしょうか。 a.compareDocumentPosition(b) は 20 (4+ 16) を返す必要があるため、a.compareDocumentPosition(b) == 20 を使用して操作できます。& 演算子を使用する利点は、これらを考慮する必要がないことです。必要な値 16 の & 演算が true を返すことができるかどうかを検討してください。 (John Resig には、compareDocumentPosition をシミュレートするメソッドがあり、IE でも適用できます。興味がある場合は、記事の最後にあるリンクを参照してください~)

ビット単位の左シフト演算: ビット単位であることがわかっています。 1 ビットの左シフトは 2 倍されます。この場合、a*2 の代わりに a

ビット単位の右シフト: a/2 の代わりに a>>1 を使用することもできます。さらに、ビット単位の右シフトでは、小数を 3.1415>>0=3 などの整数に簡単に変換できます。ビット単位のシフト演算のオペランドは整数型である必要があります (詳細については ECMA-262 マニュアルを参照してください)。そのため、小数点以下の桁は演算後に破棄されます~

注: ビット演算子は数値オペランドが整数である必要がありますタイプ、およびこれらのオペランドが使用されます。 32 ビット整数として表され、32 番目のビットは符号ビットです。さらに、オペランドは 32 ビット整数の範囲に制限されており、右側のオペランドは 0 ~ 31 である必要があります。 (この記事のバイナリエンコーディングは標準化されておらず、便宜上のものです~)


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。