対象読者
- データ型がなぜ必要なのか知りたい方
- オブジェクト指向のクラスがなぜ登場したのか理解したい方
結論
データ型とは、機械が扱うことのできるオン/オフの羅列(ビット列)を解釈するための付加情報である。データ型のおかげでヒトはビット列がどうかとか気にせずに、より高度なことに頭を使うことができるのだ。プログラミングには欠かせない要素だ。
データ型はより少ない情報量で、より多くを表現できるように、言い換えると、表現の経済性を高めるように進化してきた。
さらにデータ型はビット列の解釈という枠を超えて、データの振舞いすらも定義するように拡張され、オブジェクト指向のクラスへと結実する。
本記事では、データ型の進化の軌跡を追う。
数値の表現の進化
まずはコンピュータで数値を扱うためにどのような工夫がされてきたのかを見ることで、データ型の意義を確認する。
その前に、コンピュータがなかった頃に事情を見る。
計算機以前の数の表現
昔々、ヒトは指を折ってオン/オフを表現することで、数を数えてきた。桁や数字を表す「digit」という英単語が指という意味を併せ持つところにその名残がある。
指折りで数える方法には欠点がある。値を保持できない点だ。しかし、後に壁に印を書いたりして、数え合上げた値を保存できるようになった。
値の保存が可能となったことにより、ヒトは数値同士の比較を行えるようになった。それによって、ヒトはより高度に数値について考えることができるようになった。
そして、数字が開発され、アラビア数字によって、位取りという便利な書き方が普及した。位取りによって大きな桁の数を簡単に扱えるようになった。
位取りの考え方を使えば、両手で10までしか数えられなかった。左手を2桁の位、右手を1桁の位とし、6進数として扱えば、0~35までの値を数えることが可能となる。
このように数値の表現は進化してきた。
数値の表現
10進数の1桁分、つまり0から9までの数値を表現するために、オンオフの情報(ビット数)は何個必要なのだろうか。以下に、数値の表現方法ごとに表でまとめた。
手法 | ビット数 |
素朴な方法 | 9 |
7セグメントディスプレイ | 7 |
そろばん | 5 |
excess-3 | 4 |
結論を言えば、10進数はなく、2進数を扱うように変更することで、最小限のオンオフ情報で最大の表現ができる。
素朴な対応
単純に考えられる方法は、指折りで数を数えるのと同様の方法だ。9個のランプ(ビット列)を用意し、順にオン(1)にしていくことで0から9までを表現できる。でも、この方法にはかなり無駄がありそうだ。
7セグメントディスプレイ
7セグメントディスプレイとは、電卓で表示される数字みたいに数値を表現する手法だ。7個の区分けされたランプ(ビット列)によって、1つの数字を表現する。これにより、素朴な表現よりも2ビット削減できる。
そろばん
皆さんご存じのそろばんでは、1桁の数値を5つの玉で表現できる。玉が上側に1つ、下側に4つと分けて並べられていて、上の玉は5として数える。これは5進数の位取りだと考えられる。位取りを使えば、より効率的な表現が出来そうだ。
excess-3
excess-3では、4ビットの情報で0から9までを表現する。4ビットの情報では\(2^4=16\)通りを表すことができるので、そのうちの10通りを0から9に対応させる、という手法だ。
しかし、本来ならば、16通りを表現できるのに、内6個は無駄にしてしまっている。もったいない。
そもそも、10進数をオンオフで表すのは非効率
- excess-3が一番ビット数が少なく済んでいるが、6通り分を無駄してしまっている。
- 位取りが経済的な表現に良さそうだ
以上より、そもそも10進数ではなく、2進数で位取りで表すのが最も経済的に良さそうだ。
これが実際に使われている整数型のビット表現の基礎だ(符号を表すビットが先頭に付いていたりするが)。
実数の表現
整数のビット表現の効率化については分かった。では、実数の表現はどうすればよいだろうか。それは、指数で表すことだ。すなわち、仮数部と指数部に分けて数値を表現するわけだ。
固定小数点数
浮動小数点数
FORTRANという数値計算に特化した言語がある。x = 1 + 3みたいに数式をそのまま書くことができるようになった初めての言語だ。でも、初期の頃、データ型として用意されていたのは数値型と文字列型のみだったようだ。
C言語では真偽値を整数で代用して書く習慣がある。1ならば真(厳密には0以外)、0ならば偽として扱うことができる。でも、そんな恣意的なルールは少し分かりにくい。真偽値であるはずなのに、足し算などの不適切な操作ができてしまうことに問題がある。
そこで、真偽値を扱うためのデータ型が登場する。論理型だ(ブール型、Booleanとも)。
ここまでで何が言いたかったかというと、文字列型や整数型、実数型などでビット列のそれぞれの位置で全く意味合いが異なる、ということだ。
従来ばらば、直接ビット列に対して操作することにより、数値をインクリメントしたり、文字を小文字から大文字に変換したりしなければならなかっただろう。しかし、ビットに対する直接的な演算はあまりにも機械側に近すぎていて、それを表すコードは全く人間の意図を反映していない。そこで、データ型を導入し、人間に分かりやすい書き方が行えるようにすることで、コードの可読性を増したり、意図を明確に表すことが可能となる。
これがデータ型の従来の役割だ。
これをさらに拡張する、つまり、ユーザが定義できるデータを導入することにより、よりまとまりのある変数のかたまりを表すことが可能となった。
なので、誤って文字列型にプラス1をしようものならば、意図と異なる結果になり得る。例えば、田んぼの”田”に対してプラス1する、というのはどういう意味を持つのか。
型付け
静的型付け
動的型付け
総称型
オブジェクト指向へ
論理型の登場ALGOL60
構造型プログラミングの潮流の中生まれた
制御手順は機械に自動で判断してもらう(自動プログラミング)
1964 BASIC 文字列型、数値型のみ
BASIC, PL/1 文字列にも足し算ができる -> 文字列型を数値型と同じくらい重視
1965 PL/1(Programming Language 1という大風呂敷な名前)次元付き集合体型(多次元配列)
構造体型(構造体)-> ユーザー定義型という潮流
ALGOL68 C言語のルーツ
1968 Simula
関数型プログラミング 型クラス モナド
参考
- セグメントLED制御(合同会社パレットソフト)
- コーディングを支える技術
- ソフトウェアの20世紀
コメント