JavaScript における負の数値の算術右シフトと論理右シフトは非常にわかりにくく、特に論理右シフトは >>> 小さな負の数値でも右シフトすると非常に大きな数値になることがわかります。
論理右シフトでは、符号ビットが全体とともに右に移動することがわかります。これは、符号があるため、最終結果は正の数になります。ビットが存在しません。まず、論理右シフトで 32 ビットの数値を生成する必要があります。次に、負の数値の符号ビットが 1 になります。これは、32 番目のビットから符号ビットまでの位置がすべて 1 で埋められることを意味します。小さい? 例: -1、論理 0 ビット右シフトの式は 1111 1111 1111 1111 1111 1111 1111 1111 です。このような数値は正の数として扱われます。したがって、-1 を論理的に N ビット右にシフトすると、最終結果はすべて 1 になります。
左シフト演算では、数値の符号ビットが保持されます。たとえば、-2 を 5 ビット左にシフトすると、64 ではなく -64 が得られます。 「シンボルはまだビット 32 に保存されていますか?」 はい、しかしこれは ECMAScript のバックグラウンドで行われるため、開発者はビット 32 に直接アクセスできません。負の数値をバイナリ文字列として出力した場合でも、負の符号を付けて表示されます(例:-2の場合は-10と表示されます)
符号付き右シフト演算
はい シンボリック右シフト演算子は、2 つの大なり記号 (
var iOld = 64; // バイナリ 1000000 に等しい
var iNew = iOld >> 5; // バイナリ 10 に等しい10 進数 2。同様に、数字を移動すると空白が作成されます。今回は、空のビットは数値の左側、符号ビットの後にあります。 ECMAScript は、以下に示すように、これらの空のビットを符号ビットの値で埋めて、完全な数値を作成します。
符号なし右シフト演算子
符号なし右シフト演算子は次のとおりです。 3 つの大なり記号 (>>>) で与えられる場合は、符号なし 32 ビット数値のすべての桁が全体として右にシフトされることを意味します。正の数の場合、符号なし右シフト演算の結果は、符号付き右シフト演算の結果と同じになります。
符号付き右シフト演算の例を使用すると、64 を 5 ビット右にシフトすると 2 になります。
符号なし右シフト演算は、すべての空のビットを 0 で埋めます。正の数の場合、これは符号付き右シフト演算と同じように動作しますが、負の数は正の数として扱われます。
符号なし右シフト演算の結果は 32 ビットの正の数であるため、負の数の符号なし右シフト演算の結果は常に非常に大きな数値になります。たとえば、-64 を 5 ビット右にシフトすると、134217726 が得られます。この結果が出たらどうしますか?
これを実現するには、数値を符号なしの同等の数値に変換する必要があります (数値自体はまだ署名されていますが)。これは次のコードで取得できます:
var iUnsigned64 = -64 >>> 0;
次に、Number 型の toString() を使用して、基数 2 を使用して実ビット表現を取得します。 コードは次のとおりです。
alert(iUnsigned64 .toString(2) ));
これにより、符号付き整数 -64 の 2 の補数表現である 11111111111111111111111111000000 が生成されますが、これは符号なし整数 4294967232 と等しくなります。
このため、符号なし右シフト演算子を使用する場合は注意してください。
次に、負の数の算術右シフトについて話しましょう>>:
-9>>2=-3 であることがわかりました。なぜ -3 なのでしょうか?
まず、符号ビットは変更されず、右シフトに参加しません。次に、9 の右シフト中に、最下位ビットが 1 の場合、右シフト後も最下位ビットは 1 のままです。シフト!これはとても不思議なことです。