web-dev-qa-db-ja.com

JavaScriptで「x <<〜y」は何を表していますか?

JavaScriptで「x <<〜y」は何を表していますか?

私はビットごとのSHIFT操作がこれを行うことを理解しています:

x << y AS x * 2y

チルダ~演算子は次のことを行います。

~x AS -(x+1)

したがって、私は次のことを前提としています。

5 <<〜3 AS 5 * 2-4 または5 * Math.pow(2、-4)

結果は0.3125になります。

しかし、5 << ~3を実行すると、1342177280になります。

段階的な説明とは何ですか?この操作の組み合わせが1342177280ではなく0.3125になる理由と理由

(この質問は、ビットごとのSHIFT演算子について、Stack Overflowの質問と似ていますビットごとの演算子とは。 )

55
vadi taslim

_x << -n_はx << (32 - n)と等しい
_~3 == -4_ so
_5 << ~3_ === 5 << (32 - 4) === _5 << 28_これは_1,342,177,280_です

正確にするためにX << -nはX <<(32-n)と同じではありません...実際、より単純でより複雑です...ビットシフト演算子の有効範囲は0〜31です...ビットシフト演算子のRHSは、まず符号なし32ビット整数に変換され、次に31(16進1f)でマスクされます(バイナリ_11111_)

_                   3 = 00000000000000000000000000000011  
                  ~3 = 11111111111111111111111111111100
       0x1f (the mask) 00000000000000000000000000011111
                       --------------------------------
            ~3 & 0x1f  00000000000000000000000000011100 = 28
_

マグニチュードが32未満の場合は、上記で投稿したものとまったく同じです。

ビット演算は32ビット整数で機能します。負のビットシフトは意味がないため、正の32ビット整数にラップされます

<<演算子 のしくみ

Rhsは、ここで説明するように、符号なし32ビット整数に変換されます ToUInt32

ToUint32は基本的に数値を取り、2 ^ 32を法とする数値を返します

53
Jaromanda X

_~_演算子はアイテムのビットを反転しますが、_<<_はビット単位の左シフトです。ここでは、バイナリでステップバイステップで何が起こっているかです。 最も左側のビットが1であることは負の数を意味することに注意してください。この形式は 2の補数です。

_3         // (00000000000000000000000000000011 => +3 in decimal)
// ~ flips the bits
~3        // (11111111111111111111111111111100 => -4 in decimal)
// The number 5 (..00101) shifted by left by -4 (-4 unsigned -> 28)
5         // (00000000000000000000000000000101 => +5 in decimal)
5 << -4   // (01010000000000000000000000000000 => +1342177280 in decimal)
_

最後の行では、ビットがシフトされて反対側に「回転」され、大きな正の数になります。実際、負の数によるシフトはビット単位のローテーションに似ています(オーバーフローしたビットは反対側にローテーションされます)。ここで、正の数によるシフトはありません。そのような行動。欠点は、回転されていないビットが無視されることです。基本的には、_5 << -4_が5 << (32 - 4)を実行することと同じであることを意味します。むしろ、回転は実際には大きなシフトです。

これは、ビットシフトが5ビットunsigned整数であるためです。したがって、2の2進数compliment-4 (11100) unsignedは_28_になります。

22

〜3(11100)(3(00011)のビット補数))を-4として解釈すべきではないが、符号なし(つまり、負ではない)5ビット整数、つまり28 = 16 + 8 + 4(11100)。

これは ECMAScript標準[〜#〜] nb [〜#〜]で説明されています。負の整数は、メモリ内で 2の補数 表現を使用して表されます):

12.8.3左シフト演算子(<<)

注右のオペランドで指定された量だけ、左のオペランドに対してビット単位の左シフト演算を実行します。

12.8.3.1ランタイムセマンティクス:評価

ShiftExpression:ShiftExpression << AdditiveExpression

  1. LrefをShiftExpressionの評価結果とする。
  2. LvalをGetValue(lref)とします。
  3. ReturnIfAbrupt(lval)。
  4. AdditiveExpressionを評価した結果をrrefとします。
  5. RvalをGetValue(rref)とします。
  6. ReturnIfAbrupt(rval)。
  7. LnumをToInt32(lval)とします。
  8. ReturnIfAbrupt(lnum)。
  9. RnumをToUint32(rval)とします。
  10. ReturnIfAbrupt(rnum)。
  11. ShiftCountをrnumの最下位5ビット以外のすべてをマスキングした結果とします。つまり、rnumと0x1Fを計算します。
  12. LCountをshiftCountビットだけ左シフトした結果を返します。結果は符号付き32ビット整数です。
9
hkBst

~xは、x値のビット表現を逆にします(32ビットの符号付き値で2の補数)。

x << yは左シフト演算子(ここでは左)です。あなたの数学的解釈は正しいです:)

ビットワイズ演算の詳細については、こちらをご覧ください。 Javascriptのビットワイズ演算子

7
Mr_Pouet

5 << ~35 << -4と同じ結果になります。

重要なこと:x << yをシフトすると、実際にはx * 2y、しかしそれは直接的な使用法ではなく、単に有用な副作用です。
さらに、マイナスのyがあると、同じように機能しません。