🙆

ITスクールの授業4日目のまと:演算子のまとめ、その2(論理演算子/インクリメント(デクリメント)演算子/ビット演算子/ビットシフト演算子)

2023/07/25に公開

前書き

今回は、単純な数字や1次元なTRUE/FALSEを決める演算でなく、コンピューターが使う数字であるビットを扱う演算子、複数の論理でもう一度TRUE(新)やFALSE(義)を決める演算子、同じであっても置く位置によって演算の順番が変わる演算など、少しは難しい演算子をまとめる。


論理の「NOT」、「AND」、「GO」演算子

  1. 「!」演算子:論理の「NOT」を示す。TRUEやFALSE前に「!」を付けて、現在の状態を逆に変える。(TRUE->FALSE, FALSE->TRUE)
System.out.println(!true); // trueを逆にした、falseが出力。
System.out.println(!false); // falseを逆にした、trueが出力。
  1. 「&&」演算子:論理の「AND」を示す。2つの被演算子がTRUEとかFALSEになる時、2つの被演算子が全部TRUEである時だけTRUEになる。2つの中でどっちかがFALSEか、両方FALSEであるとFALSEになる。
System.out.println(false && false); //2つの被演算子が全部FALSEで、FALSEになる。
System.out.println(false && true); //1つの被演算子がFALSEで、FALSEになる。
System.out.println(true && false); //1つの被演算子がFALSEで、FALSEになる。
System.out.println(true && true); //2つの被演算子が全部TRUEで、TRUEになる。
  1. 「||」演算子:論理の「OR」を示す。2つの被演算子があって、どっちか1つでもTRUEであると結果はTRUEになる。
System.out.println(false || false);
System.out.println(false || true);
System.out.println(true || false);
System.out.println(true || true);

インクリメント(デクリメント)演算子

「++」(インクリメント)と「--」(デクリメント)演算子は、被演算子の値を1足すか引くという、簡単な演算である。
しかし、この演算子を被演算子の前に置くか、後ろに置くかによって演算の順番が異なる。

  1. 被演算子の前に「++」や「--」が付くと、その行で1番先に++や--の演算をしてから他の演算をする。
int a = 1;
int b = 2;
int c = ++a + b; // aの前に「++」が付いて、aに1を足した後、「a + b」の演算をした結果が変数cに代入される。
//--> cの値は4になる。
Syetem.out.println(c) // 4が出力。
  1. 被演算子の後ろに「++」や「--」が付くと、その行の他の演算が全部終わって、1番最後に++や--の演算をする。
int a = 1;
int b = 2;
int c = a-- + 2; // 「--」がaに付いたが、演算は他の演算が終わってからする。まず「a+b」をしてcに3を代入して、1番最後に「--」が実行する。
System.out.println(c) // 3が出力
System.out.println(a) // 0が出力

個人的には、「++」や「--」が被演算子の前にあると、「前にあるから先に」と「後ろにあるから後に」というふうに考えたら覚えやすかったと思う。

  1. 「++」や「--」が使われる行で、他の演算子がない場合は前や後ろに関わらず、被演算子に値を足すか引いて終わる。
int a = 3; // 下の4行は、順番に関わらず1を足すか引く。
a--;
a++;
++a;
--a;

ビット演算子

ビット演算子は、コンピューターが使う数字である、ビットで論理演算をする演算子である。
人間が使う10進数とは違う扱い方で難しいであるが、むしろコンピューターが使う数字で直接演算をすろので、以下の長所がある。

1)ユーザー(人間)が使うデータ型をビットに変換する過程がなく、すぐビットを入力するのでもっと速い。速度が大事な場合には、ビット演算のほうが有利である。

2)人間が分かり憎い形をしているので、データの暗号化をすることに使える。

ビット演算は1つや2つも2進数の数字で、値になれる「0」と「1」を扱って演算をする。

1.ビットの「AND」演算子「&」:2つの2進数があって、同じ位置(2進数で各数値を表す位置)を値が両方「1」になっている位置だけが「1」になり、それ以外は「0」になる。
例えば、

int a = 13; //2進数にすると、「00000000 00000000 00000000 00001101」になる。
int b = 10; //2進数にすると、「00000000 00000000 00000000 00001010」になる。

int c = a & b; // 上の2つの2進数を見て、各数字のなかで、両方1になっている位置だけが1になり、その他は全部0になる。
//つまり、「00000000 00000000 0000000 00001000」になり、これを10進数にすると「8」になる。
System.out.print(c); // 「8」が出力。
  1. ビットの「OR」演算子「|」:2つの2進数があって、同じ位置の値がどっちかが「1」であると、その位置は「1」になる。両方「0」であるときだけに「0」になる。
int a = 13; //2進数にすると、「00000000 00000000 00000000 00001101」になる。
int b = 10; //2進数にすると、「00000000 00000000 00000000 00001010」になる。

int c = a | b ; // 同じ位置の中でどっちかが「1」であれば「1」になる。
//つまり、「00000000 00000000 0000000 00001111」になり、「15」になる。
  1. ビットの「XOR」演算子「^」:2つの2進数があって、同じ位置の値がお互い異なる時(各0と1である時)だけ「1」になる。
int a = 13; //2進数にすると、「00000000 00000000 00000000 00001101」になる。
int b = 10; //2進数にすると、「00000000 00000000 00000000 00001010」になる。

int c = a ^ b ; // 同じ位置の中で1つは「1」、1つは「0」である時だけ「1」になる。
//つまり、「00000000 00000000 0000000 00000111」になり、「7」になる。
  1. ビットの「NOT」演算子「~」:1つの2進数に使って、その2進数のビットを全部逆にする。
    この演算をして10進数にすると正数は負数に、負数は正数に代わる。また、元の値に1を引いた値になる。
int a = 13; // 00000000 00000000 00000000 00001101
int b = ~a; // 11111111 11111111 11111111 11110010

int c = -5; // 11111111 11111111 11111111 1111011
int d = ~c; // 00000000 00000000 00000000 0000100

System.out.println(b); // 13を-13にして、1を引いた「-14」が出力
System.out.println(d); // -5を5にして、1を引いた「4」が出力

ビットシフト演算子

ビットシフト演算しは、2進数状態の数を、左や右方向に指定した値の数ほど全体ビットを移す演算子である。
移す方向(左や右)の最後にあるビットは移されたビットに上書きされてしまう。半面、移した後に空っぽになった反対側最後ビットは演算子によって0または1で満たす。

  1. 「<<」:左の被演算子を、右の数ほど「左」側(演算子に見える方向を参考)に移す。空っぽになった右の最後のビットは「0」で満たす。
int a = 14; // 元の2進数は「00000000 00000000 00000000 00001110」である。
a = a << 2; // 左に2ほどビットを移して、「00000000 00000000 00000000 00111000」になる。(1番右のビット2つは「0」で満たされてある。)
System.out.println(a);
  1. 「>>」:左の被演算子を、左の数ほど「右」側に移す。空っぽになった左の最後のビットは「1番右にあったビットと同じ数」で満たす。
int a = 14; // 元の2進数は「00000000 00000000 00000000 00001110」。
a = a >> 2; // 右に2ほどビットを移して、「00000000 00000000 00000000 00000011」になる。
//1番左のビット2つは演算の前に1番左のビットだった「0」で満たす。
System.out.println(a);
  1. 「>>>」:「>>」とビットを移す方法は同じであるが、空っぽになったビットを必ず「0」に満たすことが違う。
int b = -4; //元は 「11111111 11111111 11111111 11111100」である。
int c = b >> 2; //左を1番左の数である「1」で満たして、「11111111 11111111 11111111 11111111」になる。--> 「-1」出力。
int d = b >>> 2; //左を必ず「0」で満たして、「00111111 11111111 11111111 11111111」になる。--> 「1073741823」出力。
System.out.println(b); 

以上で、1番目のまとめより難しい演算子を調べてみた。
ビットに関する演算子は、まだ初級である私には使うきっかけがあまりないと思うが、論理演算子やインクリメント/デクリメント演算子は制御文でよく使われるらしいので、まとめ甲斐があるようになれたらいいと思う。
次は、演算子ではあるが、制御文とも似ていてここではまとめられなかった「三項演算子」をまとめてみようと思う。

Discussion