1. 元のコード、補数コード、補数コード、正の減算から補数加算 js は 2 項演算を行うときに 32 ビットの 2 進整数を使用します。js の整数はすべて符号付きの数値であるため、最上位ビットが使用されます。 0 は正の数を表し、1 は負の数を表します。 したがって、js の二項演算で使用される整数式の範囲は
-Math.pow(2,31) ~ Math.pow(2,31)-1 // -2147483648 ~ 2147483647
元のコード: 最高ビット 0 は正を表し、1 は負を表し、残りの 31 ビットは数値の絶対値 (真の値の絶対値) のバイナリ形式です。
1 の補数: 正の数値の 1 の補数は、元のコードと同じで、負の数の 1 の補数は元のコードのビットは変更されず、残りの 31 ビットが反転されます (0 が 1 に、1 が 0 に変更されます)
補数コード: 補数正の数のコードは元のコードと同じであり、負の数の補数コードは補数コードに 1 を加えたものです (符号ビットは演算に関与しますが、実際には必要なのは -0 の補数のみです)。したがって、補数に 1 を加算するときに桁上げ演算に参加する符号ビットによって変化することを心配する必要はありません。
0 の補数: 32 個の 0 を正の数として処理し、元のコード、補数、補数はすべて 0 です。
-0 の補数コード: 最上位ビットは 1 で、残りのビットは元のコード 0 から反転され、結果として 32 個の 1 になります。
-0 の補数コード: 補数コードは 32 個の 1 になります。 1 を加算すると、最上位ビットのオーバーフローは破棄され、32 個の 0 が得られます。
したがって、正と負の 0 の補数は 0 になります。
負の数の補数から絶対値の補数を求めます。負の 2 進数の絶対値。各ビット (符号ビットを含む) が等しい限り、それを否定し、1 を加算して絶対値を取得します。
コンピュータは加算と減算を処理する際に、負の数を加算することとみなして補数コードを使用して演算を実行します。負の数を処理する場合、負の補数コードを加算することで正しい演算結果が得られます。補数コードは、Born が加算と減算の演算を統合するためのものです。
正の減算を補数加算に変換する原理は 32 ビット オーバーフローです。
32 ビットの 2 進正整数の場合、その係数は
Math.pow(2,32) = 4294967296
最大表現範囲は 32-ビットの正の整数は 4294967296 - 1 です。4294967296 に達すると、この値は 33 番目のビットに繰り上げられる必要があります。33 番目のビットはオーバーフロー ビットであり、破棄され、32 個の 0 のみが取得されます (この原理は、時針ポインタと同じです)。文字盤の0時と12時は同じ位置にあります。文字盤は12から始まるので、徐々に数字が大きくなり、Mが4294967296-1を超えると、MB94967296と表すことができます。
と負の数 -M (M は絶対値) は、正の数として表すことができます: 4294967296 - M ( この正の数は、負の数の補数に対応する 2 進の正の整数です。負の数の補数数値は 32 ビットの 2 進数であり、その元のコードの合計はモジュロとまったく同じです) 原理は、文字盤の 11 時とマイナス 1 時が同じ位置を指すのと同じです。 。
例として -3 を取り上げます。
(Array( 32).join("0") (3).toString(2)).slice(-32); // |-3| の 2 進数、つまり元のコード
元のコード = 000000000000000000000000000011;
reverse Code = 111111111111111111111111111100; // 元のコードの符号ビットは 1 で、残りのビットは反転されます
補数コード = 1111111 11111111111111111111111101; //逆コードは 1 を加算します。は、元のコードの下位 31 ビットを正の形式で反転することによって得られます。したがって、これは 2 つの数値の下位 31 ビットがすべて 1 で、補数符号ビット 1 を加えると、32 個の 1 が得られます
すると、次のようになります。
補数元コード = (補数 1) 元コード
= (逆コード元コード) 1
= 1 (32 ビットはすべて 1 の 2 進数) //補数コードは、元のコードの下位 31 ビットを正の形式で加算し、符号ビット 1 を追加すると、これら 2 つの数値の和の下位 31 ビットはすべて 1 になり、1 の補数の符号ビット 1 を加えると、32 個の 1 が得られます。
= Math.pow(2,32)
= 4294967296 //これはまさに 32 ビット 2 進数の法であり、 |-1| 11 = 12
と同じ原理です。 :正の数の減算→負の数の加算→補数の加算の処理。
2. ビット操作 js の整数はデフォルトで符号付きの正の数であるため、操作で使用できるのは 31 ビットのみであり、開発者は最上位ビットにアクセスできません。
ビット単位の演算は整数に対してのみ発生するため、浮動小数点以外の数値はビット単位の演算に参加する前に切り捨てられます。
符号ビットへのアクセスを避けるために、JavaScript は負の数のバイナリを符号のバイナリとその絶対値に変換します。たとえば、
(-123).toString(2) ;// "-1111011"
ビットごとの否定 (~): 単項演算、1 が 0 に変更され、0 が 1 に変更されます (例:
~123; //-124
このプロセスを確認できます: 正の数が反転され、符号ビットは負であるため、結果は負の数になります。 Math.pow(2,32) によれば、M は -M として表現でき、次のように計算できます
parseInt((Array(32).join(0) (123).toString(2))。 lice(-32).replace(/d /g,function(v) {
return (v*1 1)%2;
}),2)-Math.pow(2,32) // -124、負の数の場合は、Math.pow (2,32) を減算します。
JavaScript のビット演算はすべて符号付きであるため、最大 32 ビットでは最上位ビットがは符号ビットとして使用され、否定された場合は正の数が得られます (Modulo Math.pow(2,32) の補数を取得します。2 つの数値を加算すると剰余が生じ、2 つの数値は次のようになります)相互に補完します)。
整数 M のビット単位の反転は次のように計算できます:
((-1*M-1) Math.pow(2,32))%Math.pow(2,32)
ビット単位の AND (&): 2 つの数値が同じビットで、すべて 1 の場合は 1 を返し、それ以外の場合は 0 を返します
&234 = 106
"00000000000000000000000001111011"
"0000000000000000000000011101010"
---------------------- -------- ------------
"00000000000000000000000001101010"
|234 = 251
"0000000000000000000000001111011"
"00000000000000000000000011 101010"
-------- ---------- ------------------------
"00000000000000000000000011111011"
ビットごとの XOR (^): 2 数値が同じ桁の場合、一方が 1 でもう一方が 0 の場合は 1 が返され、それ以外の場合は 0 が返されます
^234 = 145
"0000000000000000000000001111011"
"0000 0000000000000000000011101010"
----------------------- -----------------------
"00000000000000000000000010010001"
XOR 演算のいくつかの機能:
a ^ a = 0
a ^ b = b ^ a
a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c
a ^ b ^ a = b
d = a ^ b ^ c a = d ^ b ^ c と推測できます //この機能は一部の暗号化アルゴリズムで使用されています
//Ifオペランドは、a=1、b=2 などの適切な範囲内にあり (オーバーフローなし)、2 つの変数の値を交換します
a = [b ,b=a][0]
/ /または
a = a^b
b = a^b
a= a^b
ビットを使用する XOR 演算は 1 つの数値を使用して複数の情報を記録します。
ステータス値には 1、2、8、16 などがあります。
これらの値の規則は、2 進数のうち 1 つだけが 1 で、残りはすべて 1 であるということです。したがって、どちらのビット単位の XOR 演算の結果も、2 つの数値の特定のビットが 1 になるという状況はなく、演算の値は一意に決まります。つまり、結果がわかっていれば、操作を行うと、それがどのような数字の組み合わせであるかがわかるため、1 つの数字を使用して複数の情報を記録できます。
00000001
00000010
00000100
00001000
00010000
1^2^4 = 7 // "00000111"
したがって、結果が 7 であることがわかっていれば、それらは 1 、 2 、および 4 の組み合わせであることがわかります。
パラメーターに複数のステータス値を含める場合は、ビットごとの OR 演算を使用できます。
そのような例では、PHP のイメージ タイプに関するいくつかの定数と PHP エラー レベルの定義を参照できます。
このような例は、10 進数で説明できます。たとえば、1 桁の数値は特定の属性のステータスを表し、10 桁の数値は別の属性のステータスを表します。この場合、各ステータスは次のようになります。 10 個の値があるため、1 つの数字で説明できる組み合わせが多数あります。
左シフト (<<): 数値のすべての 2 進ビットが左にシフトされ、符号ビットは変更されず、上位ビットはオーバーフローして破棄され、下位ビットは 0 で埋められます。
Ifオーバーフローはなく、左シフトの効果は 2 を乗算することです。
右シフト (>>): 数値のすべての 2 進ビットが右にシフトされ、符号ビットは変更されず、上位ビットは 0 で埋められ、下位ビットは破棄されます。
その効果。右シフト演算は、2で割って下に移動し、切り上げます。
符号付き右シフト (>>>): シフトするとき、符号ビットは移動に従い、符号ビットも数値として扱われるため、この演算の結果は 32 ビットの符号なしになります。整数なので、負の数の符号付き右シフトは正の整数を生成します。これは、符号ビットに対して実行できる唯一の演算です。
-123>>>1 ;//2147483586
注意事項:
オペランドが使用可能な整数でない場合、ビット演算は整数である必要があります。 0 オペランドとして
~NaN; ~0 を実行すると、結果は -1
~'x' // -1
'hello'|0; // 0
({})|0; 🎜>
ディスプレイスメント操作では 31 ビットを超えて移動することはできません。31 ビットを超えて移動しようとする場合は、ビット数を 32 で割ってシフト
123>>32 //実際の値は 123> です。 ;>0 (322 = 0)
123>>33 //実際には 123>>1
32 ビット符号付き整数の表現範囲は、-Math.pow(2,31) ~ Math です。 pow(2,31)-1 (-2147483648 ~2147483647)、js 数値の精度は倍精度、64 ビットです。2147483647 を超える整数がビット演算に含まれる場合は、バイナリ オーバーフローに注意する必要があります。 32 ビットを切り捨てた後、32 番目のビットが 1 の場合、それは負 (補数) として解釈されます。
>>0; 2147483648
>>0; //0
>>0; //1