3ビット式の表現とビットマスクの説明を「味わい」で考えてみる
甘い
辛い
苦い
みたいな食い物の記録を考えてみよう。まあ実際にはすっぱいとかいろいろあるかもしれんけど今回はこの3つに割り切って考える。ただ、味覚つーのは「甘いかつ辛い」とか「甘いかつ苦い」みたいな組合せを伴った奴が考えられる。以下はその組み合わせを全通り出してみた奴だ。
これを表計算なんかであらわすとこうなるかもしれん
ところが、もう一歩踏み込んでこれを1つの箱に閉じ込めることも可能なのであった。
たとえば以下のように考えたとしよう
甘い: 100
辛い: 010
苦い: 001
これは、桁数によって甘い辛い苦いを分離させている。これは組合せるときに便利で
甘いかつ辛いは
110
辛いかつ苦いは
011
甘くて辛くて苦い(つまり全部入り)は
111
などという表現ができることがわかる。これは
で、ここでの10進数表記は以下の説明に従ってちょ。まあ、これは表みとけば今んとこはあんま考えなくてもいいかもだが何故理論的に1とか2とか7とか出るのかってこと
ちょっと難しくなってきたけど、この0〜7の数字で「甘い」「辛い」「苦い」の組み合わせを全て表現できるわけだ。たとえばさっきの例を表にあてて考えるならば
甘いかつ辛いは
110 = 6
辛いかつ苦いは
011 = 3
甘くて辛くて苦いは
111 = 7
などと6とか3とか7とかの数字でこの3つの味の組合せが表現できてまうってことですな。
ビットマスクの説明
ここで、現実にはあんまありえねえんだけど「味わいを取り除く謎の調味料」が開発されたとしよう(そもそもこれは調味料なのか?まあいいや)。
それは辛さを取り除くことも甘味を取り除く事もできるし、その複合もできる。この場合も上記の表を用いて全部表現できるはずだ。たとえば辛さだけをとりのぞくなら
010 = 2
という謎の味抜き調味料が完成するだろうし、辛さと苦さを取り除くなら
011 = 3
という味抜きになるだろう。さて、これを実際にあてはめてみよう。
↑と同じ画像をもっかい表貼っときますよ
甘い、辛い、苦いから辛味とかを抜く
甘い辛い苦いは↑の表だと111 である。辛いは010 であった
辛味を抜きにいくとするなら010を引き去らないといけない
111 - 010 = 101
それぞれの桁から1があった場合を引き抜いて101 となる。0だったら無視する。算数というよりは各桁を抜くイメージだ。ここでは真ん中の辛味ビットに1が立ってるのでそれを抹消する。111なら
1 - 0 = 1
1 - 1 = 0
1 - 0 = 1
となるヒャクジュウイチとかヒャクイチとかじゃなくてイチイチイチって感じね。
辛さと苦さを取り除く
同様に辛さと苦さは 011 であったから、これを取り除くなら
111 - 011 = 100
となるだろう。
では辛くて苦いものから味を抜く
辛くて苦いものは011 で表現されていた
ここから辛さ(010 )を取り除く場合
011 - 010 = 001
となるし、辛さと苦さ(011)を取り除くと
011 - 011 = 000
と、理論的に味が消滅した状態(000)になる、ま、現実的にはそんなことねえんだけども、これは全て仮の話だからね。
もう一歩進んで甘いものから苦みを抜くと?
甘いだけの奴は100 と表現されていて、苦いのは001 と表現されていた。これは
100 - 001 = 100
1 - 0 = 1
0 - 0 = 0
0 - 1 = 0
となる。ここにポイントがある。
そもそも甘いだけの奴は苦い要素がないので苦みを引いてもやっぱり甘いって概念。これが例えば計算対象が甘いかつ苦い(101) だったら苦味があるためにうまいことひっこ抜ける
101 - 001 = 100
1 - 0 = 1
0 - 0 = 0
1 - 1 = 0
これがビットマスク演算の基本的な考えである。
これを10進数で考えると
111 - 010 = 101
みたいなのを10進数でやるとですな
111 = 7 (甘い+辛い+苦い)
010 = 2 (辛い)
101 = 5 (甘い+苦い)
つまり
7-2 = 5
のように綺麗にまとまるものもあれば
110 - 011 = 100
110 = 6 (甘い+辛い)
011 = 3 (辛い+苦い)
100 = 4 (甘い)
6 - 3 = 4
のようになっちゃうものもあるわけ。これは
する事がほとんどである。つまりこの場合は
甘い+辛いヤツから辛い+苦いを引き算してんだけど、そもそも苦い要素がねえから甘いだけ残るんだけど、このように苦くない奴から苦みを抜くみたいな過剰な引き算をすると10進数的な算数では計算が合わなくなるんだね。
理解できましたか?
まあこれはLinuxのパーミッションでよく出てくるけど、もう一歩進むとIPアドレスの計算的なものでも使うような概念すからね、コンピューターの世界では割と日常的に出現します…
甘いとか苦いとか適当なのじゃなくてファイルシステムのパーミッションでちゃんとrxwで書いた方がいいんならそうしますよw
で実際に計算するときはどうすんの
6 - 3
を求められたときはもうこれはビットに直すしかねえな
110 - 011
と書き直す。
まあこのやり方はいろいろあると思うけど丸暗記しちゃってもいいんじゃないかなって気もするね