今回は「ビット演算」について解説します。
変数は、メモリ上に確保されます。
そのメモリの単位は、ビット、バイト、キロバイト等です。
例えば、byte a; と変数宣言すると、
1バイト分の領域がメモリ上に確保されます。
1バイトと言う事は、8ビットですね。
そして、a = 10; と言う処理を行うと、
次のようにビットが配置されます。
変数a = 0の場合:0000 0000
変数a = 10の場合:0000 1010
要するにビット演算とは、このビットの計算の事です。
変数a = 10のような処理の場合は、
ビット自体は気にしなくても良く、
10と言う数字が大事なんですが、
ビット1つずつに意味を持たせたい場合があるので、
そういった時に使います。
また、ビット演算対象は、整数でなければなりません。
ビット演算の種類
ビット演算には、AND(アンド)、OR(オア)、XOR(エックスオア)、
ビットの反転(補数)、シフトがあります。
AND(アンド)
AND(&)は、演算対象の両方のビットが1の時だけ結果が1になります。
値1 | 値2 | 演算結果 |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
a = 0x0F & 0x55;
0000 1111
& 0101 0101
--------------
0000 0101 演算結果:0x05
AND演算の使いどころとしては、他のビットの値を変えずに
どこかのビットだけを0にしたい時などです。
OR(オア)
OR(|)は、演算対象のひとつだけでもビットが1の時は、結果が1となります。
値1 | 値2 | 演算結果 |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
a = 0x0F | 0x55;
0000 1111
| 0101 0101
---------------
0101 1111 演算結果:0x5F
OR演算の使いどころとしては、他のビットの値を変えずに
どこかのビットだけを1にしたい時などです。
XOR(エックスオア)
XOR(^)は、演算対象が異なる場合のみ、結果が1となります。
値1 | 値2 | 演算結果 |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
a = 0x0F ^ 0x55;
0000 1111
^ 0101 0101
--------------
0101 1010 演算結果:0x5A
XOR演算の使いどころとしては、他のビットの値を変えずに、
どこかのビットだけを反転させたい時などです。
ビット反転(補数)
ビット反転(~)は、演算対象のビットを全て反転させます。
値 | 結果 |
0 | 1 |
1 | 0 |
a = ~0x05
~ 0000 0101
-------------
1111 1010 演算結果:0xFA
これは、特に説明はいらないと思います。
シフト
シフト処理は、ビットをずらす処理です。
左シフト
左シフトは、その名の通り、ビットを左へずらす処理を行います。
左端のビットは切り捨てられ、右端のビットには、0が入ります。
俗に左論理シフトと呼ばれます。
a = 0x05 << 1 ずらす数を指定する
0000 0101 << 1
--------------------
0000 1010 演算結果:0x0A 右端ビットに0が新しくシフトイン
右シフト
右シフトは、その名の通り、ビットを右へずらす処理を行います。
右シフトには、右論理シフトと右算術シフトの2種類あります。
右論理シフト
右論理シフトは、その名の通り、ビットを右へずらす処理を行います。
右端のビットは切り捨てられ、左端のビットには、0が入ります。
a = 0x05 >>> 1 ずらす数を指定する
0000 0101 >>> 1
----------------
0000 0010 演算結果:0x02 右端のビットは切り捨て
a = 0x05 >>> 1 ←ずらす数を指定する。
例) >>> 1 0000 0101
0000 0010 ←右端のビットは切り捨て。
右算術シフト
右算術シフトは、右論理シフトと同じく、
ビットを右へずらす処理を行います。
右端のビットは切り捨てられますが、
左端のビットには、シフト前の最上位ビットがコピーされます。
a = 0x05 >> 1 ずらす数を指定する
0000 0101 >> 1
---------------
0000 0010 演算結果:0x02 右端のビットは切り捨て
シフト処理には、<< >> の2つのシフトに限り、
次の関係が成り立ちます。
左に1ビットシフトすると、値が2倍となる。
右に1ビットシフトすると、値が1/2となる。
回転シフト
これまでは、シフトすると左端、
または右端のビットが捨てられていましたが、
その端のビットを反対の最上位、
または最下位ビットへシフトさせて
回転させるようなシフト処理を行う事も可能です。
実現するには、演算子ではなく、
IntegerクラスのrotateLeft関数、
または、rotateRight関数を使います。