英語の勉強をしようとしていて、英語力アップ!的なサイトを沢山読んだ結果、そもそも単語や熟語の数が足りなければどうしようもないという知見を得た。
日本人の英語に対する感覚が概ね
1.試験に必要だから渋々やる
2.I love English!
3.アルファベット見ると吐き気がする
の三択なので、ちょうどいいサイトが少ないのだろうと勝手に思っている。
クラスをどう説明するか。クラスはデータ型を定義するためのものだが、ではそもそもデータ型とは何なのか、という説明が必要だと思い至った。
コンピュータの世界では、すべてが二進数で表される。文字だろうと絵だろうと音楽だろうと、全ては数値化されており、それは二進数で保存され、常に「ただの二進数の塊」として扱われている。しかも、「二進数」とかっこよく言うが、もっとよく見れば二進数とは、「ただの0と1がたくさん並んだもの」でしかない。
つまり、コンピュータ内では、全てが「ただの0と1の並びで表現されている」のである。この点において、一切の例外はない。
では、その「0と1がたくさん並んだもの」の例を見てみよう
0101
これは、ゼロイチゼロイチという、0と1の並びである。これを、「二進数で表現された整数」と考えれば、整数である以上、十進数に直すことも可能だという話になり、「十進数の5」と読むことも可能である。あるいは、「音が鳴っているかどうかの状態の推移」とし、「0を無音、1を有音」と読むと決めれば、0101は、「ピー・ピー」という音を表現しているともとれる。
全てが0と1の並びであるから、それをどう解釈するかがとても重要になってくるのである。
では、もう少し高度かつ実用的な例を挙げる。
11111101
これは、「素直に」二進数で表現した整数と考えると、253という数値になる。しかしもし、二の補数による負数だと考えれば、-3という数値になる。
これは「符号付整数です」という条件が与えられているなら、-3が正解で、「符号なし整数です」という条件が与えられているなら、253が正解ということである。どのように見るかによって、答えが変わってくるのだ。
もっとややこしい例を挙げてみる。
00111111100000000000000000000000
これは、1065353216という整数だろうか?何度も言うように、何を表現しているかがわからないと、そうだとも、違うともいえない。そこで条件を与える。「上記の0と1の並びは、浮動小数点で表現された数値である」。
そうすると、この001111...は、実は1.0という実数を表そうとして並べられたということがわかる。
※C言語の32bit浮動小数点は少し複雑だ。一番左側が0ならプラス、1ならマイナスの数であるとし、次の01を8個まとめて指数部とし、残り23個の01を仮数部としている。
以上の例から、「0と1の並びを見ただけでは、それが何を表現したデータなのか、皆目見当がつかない」ことが、わかっていただけたと思う。コンピュータで正常な計算をするには、
01の並んだ「データ」と共に、その01の並びを意図した通りに解釈する「ルール」の情報が、どうしても必要になるのである。
「データ型」とは、このルールのことなのだ。「01010101+00101111を計算して!」とコンピュータに頼んでも、「そうはいってもそれって整数?小数?符号は想定するの?そもそもそれ数として扱ってもいいの?」と、わからないことだらけで計算できない。そこで、
「符号なし整数01010101 + 符号なし整数00101111を計算して!」と、データを扱うルールと共に与えてやって初めて、「10000100」という計算ができるのである。
例えば、以下のプログラムを見てみる。
char A = 10;
これはまずAという変数名に、charという型情報が紐づけられる。今後Aという変数が出てきたら、それは8個の01で表現した整数であるとみなしなさいと、コンパイラに命令しているのである。以後、Aは整数として扱われることが保証され、万が一、浮動小数点演算などが入れば、「プログラマのおまえが整数として扱えと言ったのに、なんで浮動小数点演算をさせようとするんだ?正気か!?」と、コンパイラが警告を発するようになる。
つまり、新たなデータ型を作るとは、ある0と1の並びに対して、どう扱うか?というルールを、新たに作ることなのである。
では、実際にルール、つまりデータ型を作ってみる。作るといっても、計算して求める作業ではない。どういう風に計算するかという決め事を作ることなので、一般的に、「データ型を定義する」という表現のほうが好まれる。
ルールを作るためには、まず「何をしたいか」を明確にしなければならない。ここでは単純に、複素数を計算したいという目的を設定する。
複素数は、
3+4i
のように、二つの整数で表す。(実数にすると二進数での表現が複雑になるから)
これをどのように0と1で表現するかだ。まず、iや+といった記号を書くことはできない。0と1以外ないからだ。そうすると、並んだ順番で判断するのが最も妥当そうだ。
00110100
はて、これがなぜ3+4iになるのか。それは、
0011 0100
と、4桁ごとに区切り、左側を実数部、右側を虚数部と表す。そのように今、著者である私が決めたからだ。そして、「足し算を行うときは、実数部ごと、虚数部ごとに行い、4桁の区切りを跨がない」というルールも作っておく。01を解釈するルールを作ったからには、それに対して計算をするときのルールも必要になるのだ。
それでは、このルールで1+1iを0と1で表現してみよう
00010001
では、 (3+4i) + (1+i1)を計算してみよう
実数部 | 虚数部 |
0011 +0001 -------- 0100 |
0100 +0001 -------- 0101 |
従って、この答えは、
01000101ということになる
この複素数を表示するときは、
01000101 という0と1の塊を、右と左に分け、
● 0100を4桁の二進数整数とみなし「4」を表示し、
● +を表示し、
● 0101を4桁の二進数整数とみなし「5」を表示し、
● iを表示する
という手順になる。間違って、コンピュータに「符号なし整数01000101」を表示して!」と命令してしまうと、69という値が出力される。コンピュータは、人間が指示した通りの仕事をするのである。人間の意図は関係ない。