アットウィキロゴ

ビット演算子

ビット演算子

一気に難しくなるかもしれないから
これより前のがわかってなかったり
2進数ってのがわからなかったら見ないほうがいい



ビット演算っていうのは2つある整数を2進数に直してから
決められた処理で
  • 新しい値を出す
  • 値を抜き出す
  • 値を計算する
  • その他いろいろ
ってことを言うんだ

それを出す記号は次の通り
記号 意味?
& AND
OR
^ XOR
~ NOT
>> 右シフト
<< 左シフト

なんか前にもこんなの見なかった?
たしかに論理演算と似てる記号があるけど
搾り出す数字は論理演算とはまったく違う値が出てくるんだ

使い方は論理演算と同じように2つの数値の間に挟んでやればいい
7 & 13

AND

ここからが本題
簡単な説明方法が見つからなかったんで
適当に処理のされかたを説明していく

まずはこれの両方の数値を
7 & 13
2進数に変えられる(8bitとして計算してみよう)
00000111 & 00001101
次にいよいよ&記号の出番
この記号は同じ数字の位の両方が1だった場合、新しい値の同じ位に1を、そうでなかったら0を
位ごとに論理演算をしてると思うといいよ
00000111 & 00001101 = 00000101
ここから出てきた値が再び10進数に直されて俺たちの画面に表示される
つまり最終的に"5"が帰ってくる

途中の&の処理をもう一度見てみよう
0 0 0 0 0 1 1 1
0 0 0 0 1 1 0 1

これの同じ位の数字でANDの処理をすると・・・
0 0 0 0 0 1 1 1
AND AND AND AND AND AND AND AND
0 0 0 0 1 1 0 1
0 0 0 0 0 1 0 1 結果

こういうこと

OR

ORの計算に関しても同じように
00000111 | 00001101
と書く

ORは同じ位の片方が1だったら1をってことで
00000111 | 00001101 = 00001111
こういう結果が返ってくる

わかりやすく見るとこんなかんじ
0 0 0 0 0 1 1 1
OR OR OR OR OR OR OR OR
0 0 0 0 1 1 0 1
0 0 0 0 1 1 1 1 結果
これが10進数に直されて15が帰ってくる

XOR

XORっていうのは
同じ位の片方『だけが』1だったら1を返す

わかりやすく見るとこんなかんじ
0 0 0 0 0 1 1 1
XOR XOR XOR XOR XOR XOR XOR XOR
0 0 0 0 1 1 0 1
0 0 0 0 1 0 1 0 結果
これが10進数に直されて10が帰ってくる

NOT

NOTっていうのは数値の直前に書いてやればいい
~9

逆にすればいいってことはこれはTRUEだからFALSEにすればいいわけ?
ビット演算の場合はそう簡単にはいかないんだ

~9を例にしてみてみると

まず2進数に変える
0 0 0 0 1 0 0 1
これの各位を逆に
1 1 1 1 0 1 1 0
つまり答えは246ってこと?
答えは-2

何でこうなるか

パソコンは電気を「流しているか」「流していないか」
つまり「1」と「0」だけで処理をしてるんだ
それでPCの中で2進数表現してるのはわかると思うけど
それにマイナスを付け加えるのはどうやってるんだろう

それはやっぱり人間と同じように数値の先頭に”マイナス”という目印を付けて
「これはマイナスの数だ!」って判断してるんだ

パソコンがマイナスと判断する材料もやっぱり0か1で
変数に格納された値の先頭が1だった場合
その変数の値はマイナスというふうに考えてるというわけ

ここで注意したいんだけど
マイナスの数は少し変で
-1という数を11111111という表現をするんだ

どうしてこうなったかっていうと…
たしか正の数を反転した数がそのままマイナスになるようにしたかったんじゃなかったっけ
そうした時に
00000001を反転すると11111110になるんだけど
そうなると11111111って数を使うとすると
  • 0という数字が出来てしまうことになる(数学上こういう値は存在しない・・はず)ので
「このムダを無くそう!」ってなかんじから

マイナスの値は
正の値のマイナス値 = NOT(正の値)+1
こんなかんじにして
マイナスの値を11111111から始めるようにした

…こんな感じだったと思う

これの事を2の補数って言うんだ

マイナスの値はこんな感じに書かれる
11111111 -1
11111110 -2
11111101 -3
11111100 -4
11111011 -5

シフト

右シフト・左シフトっていうのは
2進数に直した値の各位を横にずらすことを言うんだ

11 << 2
たとえばこの左シフト場合
11を2進数に直してから
00001011
各位を<<だから左に2ビットずらすって意味がある
00101100
これで出た答えが44

右シフトの書き方も同じ
11 >> 1
たとえばこの左シフト場合
11を2進数に直してから
00001011
各位を>>だから左に1ビットずらす
00000101
これで出た答えが5

これらって何の意味があるの?

ビット演算っていうのは普通にやる*とか+の計算より処理が軽いらしい
それに使い方次第ですごく便利な物に変わる

この処理を見てほしい
a = 1;
a |= 2;
a |= 8;
aに1を入れて
aと2をOR演算したのをaに入れて
最後にaと8をOR演算したのをaに入れるというプログラム

この状態でaの中は2進数であらわすとこんな感じになってる
00001011

これは各位を色んな条件と見立てて
if(a & 8){}
といった感じで
00001011 と 00001000 を

0 0 0 0 1 0 1 1
AND AND AND AND AND AND AND AND
0 0 0 0 1 0 0 0
こんな感じでAND演算してるんだ
つまり帰ってくるのは8 でTRUE

もしも
00001011
これが
a |= 8;
この処理をされてなくて
00000011
こうだったら

0 0 0 0 0 0 1 1
AND AND AND AND AND AND AND AND
0 0 0 0 1 0 0 0
この処理を通した結果かえってくるのは0 =FALSE
というわけでif文は実行されないって訳

どういうことかというと
いちいちいくつも整数型の変数を作らなくても
いくつもの条件を1つの変数で高速に済ませられるってわけだ


他にもシフト演算なんかは
2進数の「左に1ずれると元の数×2」という性質を使って

integer a = 150;
a = a << 4;
こうする事でaには150*(2^4)された値=2400が出てくる

タグ:

+ タグ編集
  • タグ:
最終更新:2008年02月29日 01:43
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。