これから先「ポインタ」というものを見ていこうと思うのですが、そのためにまず「変数ってなんなの?」ってことをはっきりとさせておくべきかなと思って、変数の中でも特に重要であろうと思われる整数値に絞って解説してみました。 |
コンピューターのデータと各用語
ちょっと大変ですが、コンピューターそのものの話と、用語について。 コンピューターのデータはすべて0と1で表されます。これはオセロのコマの裏表のようなものだと考えてください。データを蓄える場所=メモリには、この「オセロのコマ」がいっぱい並んでいて、それぞれが「裏」や「表」になっていて、データが格納されているというようなイメージを浮かべると、分かりやすいと思います。
このコマひとつを「ビット」という単位で表します。コマの裏表を1と0で表すと、1ビットはこの2種類の状態を持つことになります。
ビットは「2進数」です。つまり「2になったら一桁繰り上がり、元の桁は0になる」ということです。普通日常生活で使う「10進数」は、10になったらひとつ繰り上がります。これと比べてみてください。例えば「0101」に1を足せば、一番右の位が「1+1=2」になって「繰り上がり+0」になり、「0110」という結果になります。
ビットはあまりにも単位が小さいので、普段は使用しません。普段は次のふたつの量を使って計算します。
さて、もうひとつの量は「バイト」です。バイトは16進数で2桁、つまり8ビットを表します。10進数だと「2の8乗=256」種類のデータを格納できるということになります。 |
整数の中身
さて問題です。−1と4294967295は等しい? ま、結果は次のコードを試してみれば一目瞭然でしょう。 |
if( 4294967295 == -1 )
TRACE( "Hit(4294967295 == -1)\n" ); //ヒットです、これ。
なんでこんなことになってしまうんでしょうか。ま、これはかなり極端な例ですが、C言語での「データの扱い」というものを的確に表していると言えるでしょう。とゆーわけで、比較的よく使う「整数」というものについて見てみましょう。
整数値の場合、ビットの並びをそのまま整数として数えます。例えば「0000」は「0」、「0001」は「1」、「0010」は「2」といった感じです。この数え方でいくと、この4ビットのデータは1〜15まで表せることになりますね。基本はこんな感じです。
上で書いた「4294967295」の数字が当てはまるのが「符号ナシ整数値」です。符号ナシ整数値は32ビットのデータすべてを数字に使うことができるので、0から4294967295までの数字を表すことができます。 |
UINT uiTest1 = 4294967295;
TRACE( "%d, %u, %X\n", uiTest1, uiTest1, uiTest1 );
// -1, 4294967295, FFFFFFFF
TRACE()で使う書式はprintf()の「書式指定」の項目を見てください。
さて、その書式指定で「%X」を指定すると、変数の中身を16進数の形で表示します。この結果はすべてF。0から数えていって、一番大きい数字を表すわけですから、当然ですね。 右から2番目の「%u」は、変数の中身を符号ナシ整数値とみなして表示します。UINTはその通りのものなので、結果は同じ4294967295が出ます。 さて、一番左の「%d」。これは符号あり整数値とみなして表示するというものです。つまりこれは「FFFFFFFF」というデータがあったとき、符号あり整数値では−1という意味だということなのです。
では、ここから「符号あり整数値」について見てみましょう。 |
マイナスと「2の補数」
16進数で「マイナス」を表すときには、一番上のビットを1にするだけではできません。その証拠に、−1はFFFFFFFFです。この特殊なマイナスの数字は「2の補数」という方法を使って求めます。 「2の補数」の言葉の意味は考えなくていいです。単に方法だけ憶えておけばいいでしょう。 方法は簡単。「ビットを反転し、1を足す」だけ。例えば「0101」(5)なら、ビットを反転して「1010」、これに1を足して「1011」。これが「−5」を表します。簡単ですねー。ビット数は違いますが、「0001」なら「1111」、つまり0xFとなります。これで−1がFFFFFFFFになる理由が分かりましたね。
なんでまたこんなめんどくさいことをするのかというと、2の補数を使うと「足し算で引き算ができる」からです。んなバカな、と思うかもしれませんがちゃんとできてしまうのです。
ちなみに「なんで足し算で引き算ができるんだよーっ!!」という人のために、簡単な例で種明かしをしましょう。
さて次に、確認のために「10進数」で2の補数を使った引き算を実行してみましょう。同じく例は「7−4」にします。
これを、簡単な例と図を使って説明しましょう。
これと同じことを2進数でも行うことで、足し算と2の補数を使って引き算ができてしまうのです。ただその中で、「反転して1を足す」というテクニックを用いている部分がちょっと違うくらいです。 |
つづく
ちょっと長くなっちゃたので、次回に続きます。 |
(C)KAB-studio 1998 ALL RIGHTS RESERVED. |