第六章 ビット演算子
ビット論理演算子
ビット演算子は値をビット単位の編集する演算です。
ビット論理演算子は、 0を「false」、1を「true」 に見立てて論理演算をします。
& | ^ ~
int以外の整数やbooleanでも使えるが、
intを前提として説明していこう。
目次
1. ビット論理演算子
ビット演算は、intの 32桁のビット列に対してビット単位の編集を行います。
ビット論理演算子は、32個あるそれぞれのビットに対して、論理演算を行うものです。
ビット論理演算子
- それぞれの桁の 0を「false」、1を「true」 に見立てて、
ビットごとに論理演算をします。
- 関係が正しければ1を、誤りであれば0で返します。
- すべてのビットを評価した結果を、整数として返します。
難しいかな?
実例を見てもらった方が
いいな。
2. ビット論理演算子の種類
ビット論理演算子は以下の4種類です。
ビット論理演算子の種類
| 演算子 | 記述例 | 説明 |
| & | x & y | ビットごとのAND演算を行う。 |
| | | x | y | ビットごとのOR演算を行う。 |
| ^ | x ^ y | ビットごとのXOR演算を行う。 |
| ~ | ~x | ビットごとのNOT演算(各ビットの反転)を行う。 |
あ!
論理演算子?
ちょっと違うけど。
ホントだ。
そっくりっすね。
そう。
ビット演算は
ビットごとに論理演算を行う。
3. AND(論理積)
&
「&」は、0を「false」、1を「true」 に見立てて AND演算をします。
2つのビットが両方とも 1 であれば、結果は 1 です。
その他の組み合わせは 0 です。
&演算子
| xのビット | 0 | 0 | 1 | 1 |
| yのビット | 0 | 1 | 0 | 1 |
| 結果 | 0 | 0 | 0 | 1 |
1ビットごとに上の表の様な
評価を行う。
1ビットごとに?
例えば、01011101 & 00001111 を計算してみましょう。
ここで、01011101 は、10進数で 93、 00001111 は、10進数で 15ですが、
数値としての値を利用するのではなく、ビット列として利用します。
x = 01011101
y = 00001111とします。
01011101 & 00001111
| x = 01011101 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 |
| y = 00001111 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
| x & y | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 |
x と y の両方が 1の桁 → 1
それ以外の桁 → 0
とすると、00001101 になります。
答えは、00001101です。
なんだか暗号解読
してるみたい。
プログラムでも書いてみましょう。
後半部分は2進数として表示するためのコードです。
今はスルーしてください。
ホントは32桁を0埋めするのが正しいが、
見づらいので 8桁で我慢しよう。
//Sample06_21.java
class Sample06_21 {
public static void main(String[] args){
int x = 0b01011101;
int y = 0b00001111;
int ans = x & y;
String binStr = Integer.toBinaryString(ans);//2進数の文字列
binStr = String.format("%8s", binStr);//8桁
binStr = binStr.replace(' ', '0');//0埋め
System.out.println(binStr);
}
}
コマンドライン
>javac Sample06_21.java
>java Sample06_21
00001101
4. OR(論理和)
|
「|」 はOR演算をします。
2つのビットが両方とも 0 → 0
その他の組み合わせ → 1
|演算子
| xのビット | 0 | 0 | 1 | 1 |
| yのビット | 0 | 1 | 0 | 1 |
| 結果 | 0 | 1 | 1 | 1 |
例えば、01011101 | 00001111 を計算してみましょう。
01011101 & 00001111
| x = 01011101 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 |
| y = 00001111 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
| x | y | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
答えは、01011111です。
5. XOR(排他的論理和)
^
「^」 はXOR演算をします。
2つのビットのいずれか片方が 1 → 1
両方が 1 、又は両方が 0 → 0
^演算子
| xのビット | 0 | 0 | 1 | 1 |
| yのビット | 0 | 1 | 0 | 1 |
| 結果 | 0 | 1 | 1 | 0 |
例えば、01011101 ^ 00001111 を計算してみましょう。
01011101 & 00001111
| x = 01011101 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 |
| y = 00001111 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
| x ^ y | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 |
答えは、01010010です。
6. NOT(否定)
~
「~」 はNOT演算をします。
1 であれば、結果は 0 です。
0 であれば、結果は 1 です。
例えば、~01011101 を計算してみましょう。
先ずは8ビットとして計算しますね。
01011101 & 00001111
| x = 01011101 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 |
| ~x | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 |
答えは、10100010です。
ただし、これが intの場合は 32ビットになります。
01011101の前に24ビットが0埋めされているので、
24ビットの 0 が反転して、24ビットの 1 が付きます。
答えは、11111111_11111111_11111111_10100010です。
7. プログラム例
上述の例をコードにすると、以下の様になります。
//Sample06_20.java
class Sample06_20 {
public static void main(String[] args){
int x = 0b01011101;
int y = 0b00001111;
int ans;
String binStr;
ans = x & y;
binStr = Integer.toBinaryString(ans);
binStr = String.format("%32s", binStr);
binStr = binStr.replace(' ', '0');
System.out.println(binStr);
ans = x | y;
binStr = Integer.toBinaryString(ans);
binStr = String.format("%32s", binStr);
binStr = binStr.replace(' ', '0');
System.out.println(binStr);
ans = x ^ y;
binStr = Integer.toBinaryString(ans);
binStr = String.format("%32s", binStr);
binStr = binStr.replace(' ', '0');
System.out.println(binStr);
ans = ~x;
binStr = Integer.toBinaryString(ans);
binStr = String.format("%32s", binStr);
binStr = binStr.replace(' ', '0');
System.out.println(binStr);
}
}
コマンドライン
>javac Sample06_20.java
>java Sample06_20
00000000000000000000000000001101
00000000000000000000000001011111
00000000000000000000000001010010
11111111111111111111111110100010
8. ビット演算の利用例
ビット演算って
どんな時に使うの?
えっと...
情報処理系の資格を
受験するとき?
うそうそ!
画像データから色を抜き出したり、
IPアドレスをintにまとめたりするのに
使うんだ。
例えば、
画像データの1ピクセルを intで取得した際に、次のページの「シフト演算子」との組み合わせで
赤、青、緑、アルファー値の各値を取り出すのに使われます。
11111111_01010101_00001111_10101010
|-alpha-| |-red--| |-green| |-blue-|
本章の終わりに紹介させていただきます。
お楽しみに。
うーん。
初心者向けではないかな?
パズルと思って楽しんでくれ。
お疲れ様でした。