ビット演算子「~演算子とは」
前回の記事を見ると、より理解しやすいです。
syopuro.hatenablog.com
こんにちは、ビット演算子の記事もこれで最後です。記事をかくのも慣れて早く書けてる自分がいます。
最初は自分にとって非効率化と思う時もありましたが、慣れるとやはりテスト勉強前にノートをまとめるような、気持ちになれてよいですね。
では早速今回のテーマである~演算子についてやっていきましょう。
~演算子について
~演算子とは、オペラントの逆を演算する演算子です。
上記の様に例えば0なら1、1なら0の様になります。
この演算子以前の3つの演算子と異なり、マイナス符号の様に、オペラントの前につけるのが定番の使い方です。
今回はまとめも兼ねて、&.|,^演算子も織り交ぜながらプログラム書いていきたいです。
では早速2進数10進数16進数によって、違いは出るのかなど見ていきたいと思います。
2進数における~と&の使われ方。
public class Main { public static void main(String[] args) { int a=0b1010; int b=0b1010; int c=~a&b; System.out.println(Integer.toBinaryString(a)+"+"+Integer.toBinaryString(b)+"="+Integer.toBinaryString(c)); //System.out.println(Integer.toString(c)); } }
1010+1010=0
0
という演算結果になったと思います。
今日のスクリプト解説Part1
まず、aとbには、どちらも1010が代入されます。
その後
c=~a&b式があると思います。
aの前に~が有ります。これによりaに代入されている。数を反転させます。1010を0101というように、
次に反転させたaとbを&演算子で演算します。
以前勉強したように、&回路は、左のオペランドと右のオペランドが両方とも1の時に、演算結果に1が、出力されます。
そのため今回は、0101と1010なので、答えは、0になりますね。
10進数における^と~のスクリプト
public class Main { public static void main(String[] args) { int a=1; int b=3; int c=~a^b; System.out.println(Integer.toBinaryString(~a)+"+"+Integer.toBinaryString(b)+"="+Integer.toBinaryString(c)); System.out.println(c); } }
11111111111111111111111111111110+11=11111111111111111111111111111101
- 3
結果に驚きましたが、バグとかではないんです。
スクリプトの解説
まずaは1ですよね。~aは負数なので、2の32乗を二進数で表したものから、入力された数のみ反転したものでかつそこから1足したものが、負数として
表せるので、11111111111111111111111111111110となります。(桁が長いけど0と1の変化桁だけ見ればよいです。)
その数と11を^演算したもの(両方とも1の時と、両方とも0の時以外1を演算する)は、11111111111111111111111111111101が表示されますね。
演算結果を再度10進数で確認すると
-3になりますね。
演算結果を間違えたのかと思うかもしれませんが、11111111111111111111111111111101は、負数なので
一度2進数の正の数に戻すとどの数がマイナスされたの分かって、演算結果を確かめられます。
ということで、負数へ直した時の逆で、まず1を引きます。11111111111111111111111111111100
この値を反転させると、11が演算されます。
11は3と表せるの、3を負数にした。11111111111111111111111111111101が演算結果のー3と分かります。
こんな感じでスクリプトの解説は以上です。16進数と|は記事が長くなるのと結果の予想がつくので、記事にはしません。。。
負数変換の仕方。
- まず演算したい正の数の値を反転させます。
- 反転した数に+1してあげます。
正数変換はその逆の手順をするだけ、手順を間違えると演算結果が変わるので、注意
まとめ
- 負数に変換する。
- 演算結果が不安なら負数に変換の逆を行う。