私はシフト演算子を理解しようとしていますが、それほど多くは得られませんでした。以下のコードを実行しようとしたとき
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
誰かが説明してもらえますか?
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
2進数の10進数システムからの2は次のとおりです。
10
今なら
2 << 11
右側に11個のゼロが埋め込まれます
1000000000000
符号付き左シフト演算子「<<」はビットパターンを左にシフトし、符号付き右シフト演算子「>>」はビットパターンを右にシフトします。ビットパターンは左側のオペランドで指定され、シフトする位置の数は右側のオペランドで指定されます。符号なしの右シフト演算子「>>>」はゼロを左端の位置にシフトしますが、「>>」の後の左端の位置は符号拡張に依存します [..]
左シフトにより、項または算術演算で2(* 2)の乗算が行われます
たとえば
バイナリ[10
の2、<<1
を行う場合、100
は4
になります
バイナリで4 100
、あなたが<<1
を実行した場合、それは1000
になります8
参照
右シフトと左シフトは同じ方法で機能します。右シフト:右シフト演算子>>は、値内のすべてのビットを指定された回数だけ右にシフトします。その一般的な形式:
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
私はこれが役立つかもしれないと思います:
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
編集:
たとえば、次のようになります。
[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
それはその多くの0's
をパディングすることによってビットをシフトします。
例えば
10
である2進2
は、数字1000
である8
です。10
は数字2
の左に3シフトしたもので、10000
は数字の16
シフトはデータ型(char、int、long int)で実装できます。 floatデータとdoubleデータはシフトされません。
value= value >> steps // Right shift, signed data.
value= value << steps // Left shift, signed data.
符号付き左シフト論理的に単純なら1 << 11なら2048になり、2 << 11なら4096になる
Javaプログラミングでは、int a = 2 << 11;です。
// it will result in 4096
2<<11 = 2*(2^11) = 4096
変数をシフトしてその変数に代入する典型的な使い方は、省略形の演算子で書き直すことができます<< =、>> =、または>>> =、仕様では 複合代入演算子 としても知られています。
例えば、
i >>= 2
と同じ結果になります。
i = i >> 2