コンピュータ内の数

論理演算

さて、すでに四則演算に関しては述べたよな。実はこれ以外に2進数において結構、重要・・・というより、本質的な演算ってのがあるんだ。それが論理演算だ。とりあえず、ここでは紹介しておく。これもプログラマーなら常識なのでCうんぬん以前の問題としておさえてほしいと願う。

論理積

たとえば二つの数、13と9という数字について考えてみよう。13と9をそれぞれ2進数で考えてみるとどうなるか、もうわかるな。13=1101(2)だし9=1001(2)だ。これらの論理積ってものを考えてみよう。

まずは表記方法からだ。論理積は普通、andを使ってこういう風に書く。

13 and 9

1101(2) and 1001(2)

二つは単に2進数を使ったか、10進数を使ったかの違いで全く同じだ。で「論理積」だと堅苦しいのでそのまんま、アンドって言ったりもする。で、計算方法はこうやる。

  1. まず、計算したいものが10進数とか16進数で表されていたら2進数で考える必要があるので2進数に変換する。
  2. 各ビットごとに次のような操作をする。
    1. もし今、見ているビットがともに1だったら1。
    2. もし今、見ているビットの一方でも0だったら0。
  3. 順に並べて書いたものが結果。
例えば例だとこんな感じ。

1101(2) and 1001(2) = 1001(2)

あえて表にするとこんな感じ。

数1数2論理積
000
010
100
111

論理和

例によって表記方法から。で、こう書く。

1100(2) or 1001(2)

でさっきの論理積同様、「論理和」だと堅苦しいのでそのまんま、オアって言ったりもする。で、計算方法はこうやる。

  1. まず、計算したいものが10進数とか16進数で表されていたら2進数で考える必要があるので2進数に変換する。
  2. 各ビットごとに次のような操作をする。
    1. もし今、見ているビットが両方とも0だったら0。
    2. もし今、見ているビットの一方でも1だったら1。
  3. 順に並べて書いたものが結果。

1100(2) or 1001(2) = 1101(2)

数1数2論理和
000
011
101
111

排他的論理和

例によって表記方法から。で、こう書く。

1100(2) exor 1001(2)

「排他的論理和論理和」を簡単に言う方法って実は知らないなあ。エクスオアとか言うんだろうか。まあ、計算方法はこうだ。

  1. まず、計算したいものが10進数とか16進数で表されていたら2進数で考える必要があるので2進数に変換する。
  2. 各ビットごとに次のような操作をする。
    1. もし今、見ているビットが両方とも0、1だったら0。
    2. もし今、見ているビットの一方でも1だったら1。
  3. 順に並べて書いたものが結果。

1100(2) or 1001(2) = 0101(2)

数1数2排他的論理和
000
011
101
110
以上、全てまとめてみた。
数1数2andorexandexor
000010
010101
100101
111110

否定

表記方法だけどよく使われるのは次の二つ。

not 1011(2)

または単純に上付きの線を付けることも多々、ある。通常はノットと読む。で、計算方法は次のとおり。

  1. まず、計算したいものが10進数とか16進数で表されていたら2進数で考える必要があるので2進数に変換する。
  2. 各ビットごとに次のような操作をする。
    1. もし今、見ているビットが1だったら0。
    2. もし今、見ているビットが0だったら1。
  3. 順に並べて書いたものが結果。

not 1011(2) = 0100(2) (= 100(2))

数1否定
01
10

で、いったい何なのよ

この疑問、当然だ。突然、こんなわけのわからん演算を紹介されてもなあって感じだ。で、何なのかというとこれらがコンピュータ、計算機の本質なのだ。そもそも、コンピュータが"1"、"0"の世界だってどういう意味かということなのだ。

あなたが実際になにかを計算する電気回路を組むとしよう。当然、計算するわけだから数字を電気を使って表現しなければならないわけだ。どうする?

小学校か中学校で習ったと思うけど電気の量の一つに電圧ってのがあったよな。そう、単三電池は1.5Vってやつ。このボルトを使うことを思いつけると思う。で、例えば1 = 1V、2 = 2V、・・・10 = 10Vって感じだ。1.5 = 1.5Vということで少数も表現できる。で実際、こういうコンピュータも世の中にはあるらしい。アナログ計算機っていうんだ。

しかし、これ、実際は全然だめだ。なにが駄目かというと、回路のちょっとしたことで値がかわってしまうのだ。

例えば、1Vの電圧、何もしなければずっと1Vかというとそんなことは全然ない。携帯電話を近づければその電波で狂ってしまう。そうでなくても周辺回路の影響で電圧を完璧に再現するなんて不可能なのだ(それが出来たら超オーディオアンプとかもできてしまうしな)。そして、何も演算していないのに電圧が変わるというのはこの場合、値が変わってしまうことになる。いうなら、1が何もしないのに1.2になったって感じだ。これじゃあ、計算にならん。

では、どうするか。小学校のときに豆電球で遊んだだろうか。ヒントはこれ。つまり、豆電球の明るさは前に言った電圧の値そのものによるけどついているかいないかは電圧の値が少々狂っても問題ない。つまり、豆電球に1.5Vの電池を繋ごうが3Vの電池を繋ごうがついていることははっきりわかる。また、0Vだろうが0.1Vだろうがともに充分暗いのでついていないと判断できる。

もうわかっただろう。コンピュータの内部では数字は電圧の値とかで表現しているんじゃなくて電圧の組み合わせを使っているのだ。そして、我々人間が扱いやすくするため、電圧の低い状態を"0"、高い状態を"1"と割り当てただけなのだ。だから、2進数で扱い、つまり"0"、"1"の世界なのだ。

で、論理演算、これはコンピュータの本質だ。コンピュータの最深部(CPUのごく内部)ではこういう論理演算が行われているのだ。実は四則演算も論理演算だけで計算することが出来るのだ。

そういうわけなのでここで色々紹介した。C言語を知る上で全てが必須じゃないけどプログラマと名乗るなら必須以前の話なので薀蓄(うんちく)を語ってみた。はあ、疲れた。

くわしすぎるC