web-dev-qa-db-ja.com

シフト演算子はJavaでどのように機能しますか?

私はシフト演算子を理解しようとしていますが、それほど多くは得られませんでした。以下のコードを実行しようとしたとき

System.out.println(Integer.toBinaryString(2 << 11));
System.out.println(Integer.toBinaryString(2 << 22));
System.out.println(Integer.toBinaryString(2 << 33));
System.out.println(Integer.toBinaryString(2 << 44));
System.out.println(Integer.toBinaryString(2 << 55));

私は以下のようになります

1000000000000    
100000000000000000000000    
100    
10000000000000    
1000000000000000000000000    

誰かが説明してもらえますか?

132
gnreddy
System.out.println(Integer.toBinaryString(2 << 11)); 

バイナリ2(10)を左に11回シフトします。それゆえ:1000000000000

System.out.println(Integer.toBinaryString(2 << 22)); 

2進数2(10)を左に22回シフトします。それゆえ:100000000000000000000000

System.out.println(Integer.toBinaryString(2 << 33)); 

Intは4バイト、つまり32ビットです。したがって、33だけシフトすると、1だけシフトするのと同じことになります。したがって、100

200
Kazekage Gaara

2進数の10進数システムからの2は次のとおりです。

10

今なら

2 << 11

右側に11個のゼロが埋め込まれます

1000000000000

符号付き左シフト演算子「<<」はビットパターンを左にシフトし、符号付き右シフト演算子「>>」はビットパターンを右にシフトします。ビットパターンは左側のオペランドで指定され、シフトする位置の数は右側のオペランドで指定されます。符号なしの右シフト演算子「>>>」はゼロを左端の位置にシフトしますが、「>>」の後の左端の位置は符号拡張に依存します [..]

左シフトにより、項または算術演算で2(* 2)の乗算が行われます


たとえば

バイナリ[10の2、<<1を行う場合、1004になります

バイナリで4 100、あなたが<<1を実行した場合、それは1000になります8


参照

35
Jigar Joshi

右シフトと左シフトは同じ方法で機能します。右シフト:右シフト演算子>>は、値内のすべてのビットを指定された回数だけ右にシフトします。その一般的な形式:

value >> num

ここで、numは、valueの値を右シフトする位置の数を指定します。つまり、>>は、指定された値のすべてのビットを、numで指定されたビット位置の数だけ右側に移動します。次のコードは、値32を2桁右にシフトして、結果を8に設定します。

int a = 32;
a = a >> 2; // a now contains 8

値に「シフトオフ」されたビットがあると、それらのビットは失われます。たとえば、次のコードフラグメントは値35を右の2つの位置にシフトします。これにより、下位2ビットが失われ、結果としてaが8に設定されます。

int a = 35;
a = a >> 2; // a still contains 8

バイナリで同じ操作を見ると、これがどのように起こるかがより明確にわかります。

00100011 35 >> 2
00001000 8

値を右にシフトするたびに、その値は2で除算されます。残りはすべて破棄されます。あなたは2による高性能の整数除算のためにこれを利用することができます。もちろん、あなたはあなたが右端から少しもシフトしていないことを確認しなければなりません。右にシフトしているときは、右シフトによって公開されている最上位(左端)のビットは、最上位ビットの前の内容で埋められます。これは符号拡張と呼ばれ、負の数の符号を正しくシフトしたときに符号を保護するのに役立ちます。たとえば、–8 >> 1–4です。これは、バイナリでは、

11111000 –8 >>1
11111100 –4

-1を右にシフトしても、符号拡張によって上位ビットに多くの1が含まれるため、結果は常に-1のままになります。値を右にシフトしているときに値を符号拡張するのが望ましくない場合があります。たとえば、次のプログラムはbyte値をその16進文字列表現に変換します。シフトされた値は、値を16進文字の配列へのインデックスとして使用できるように、符号拡張ビットを破棄するために0x0fとANDすることによってマスクされます。

// Masking sign extension.
class HexByte {
  static public void main(String args[]) {
    char hex[] = {
      '0', '1', '2', '3', '4', '5', '6', '7',
      '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    };
  byte b = (byte) 0xf1;
 System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
}
}

これはこのプログラムの出力です:

b = 0xf1
14
star18bit

私はこれが役立つかもしれないと思います:

    System.out.println(Integer.toBinaryString(2 << 0));
    System.out.println(Integer.toBinaryString(2 << 1));
    System.out.println(Integer.toBinaryString(2 << 2));
    System.out.println(Integer.toBinaryString(2 << 3));
    System.out.println(Integer.toBinaryString(2 << 4));
    System.out.println(Integer.toBinaryString(2 << 5));

結果

    10
    100
    1000
    10000
    100000
    1000000

編集:

必ず読んでください(ビットシフト演算子の使い方)

12

たとえば、次のようになります。

  • 符号付き左シフト

[2 << 1] is => [10(2の2進数)2進数文字列の末尾に1つのゼロを追加する]したがって、10は100となり、4になります。

符号付き左シフトは乗算を使用します。したがって、これは2 *(2 ^ 1)= 4と計算することもできます。別の例[2 << 11] = 2 * (2 ^ 11)= 4096

  • 符号付き右シフト

[4 >> 1] is => [100(4の2進数)2進数文字列の末尾の1個のゼロを削除]したがって、100は10になり、2になります。

符号付き右シフトは除算を使用します。したがって、これは4 /(2 ^ 1)= 2として計算することもできます[4096 >> 11] = 4096 /( 2 ^ 11)= 2

7
Obothlale

それはその多くの0'sをパディングすることによってビットをシフトします。

例えば

  • 2桁左シフトした10である2進2は、数字1000である8です。
  • 2桁の10は数字2の左に3シフトしたもので、10000は数字の16
2
Ramesh PVK

シフトはデータ型(char、int、long int)で実装できます。 floatデータとdoubleデータはシフトされません。

value= value >> steps  // Right shift, signed data.
value= value << steps  // Left shift, signed data.
2
Student

符号付き左シフト論理的に単純なら1 << 11なら2048になり、2 << 11なら4096になる

Javaプログラミングでは、int a = 2 << 11;です。

// it will result in 4096

2<<11 = 2*(2^11) = 4096
1
sunil rana

変数をシフトしてその変数に代入する典型的な使い方は、省略形の演算子で書き直すことができます<< =>> =、または>>> =、仕様では 複合代入演算子 としても知られています。

例えば、

i >>= 2

と同じ結果になります。

i = i >> 2
0