C言語

ビットとバイトと負数について

C言語では、シフト演算子や、ビット論理積など、ビット単位の操作や、データサイズについての知識が必要となるため、ビットとバイトの理解は重要になります。
ここでは、ビットとバイトについて学んでいこうと思います。

ビット

コンピュータは、0と1の値でデータを記憶しています。この0と1の2つの組み合わせで数値を表現する方法を2進数といいます。そして、0と1を格納する1つの箱が1ビットです。これが、コンピュータが扱う最小の単位となります。
普段、私たちが数値として0~9の10種類を使って表現していますが、これを10進数と言います。
1ビットは、0と1の2種類で、10進数でも、0~1で表現します。
2ビットは、00、01、10、11の4種類で、10進数では、0~3で表現します。
3ビットは、000、001、010、011、100、101、110、111の8種類で、0~7で表現します。

これは、nビットの種類は、2のn乗で表現ができます。
例えば、1ビットでは、2の1乗で2種類、2ビットでは、2の2乗で4種類、3ビットでは、2の3乗で8種類というように導きだせます。

2進数と10進数の変換表を次に示します。

2進数10進数
00000
00011
00102
00113
01004
01015
01106
01117
10008
10019
101010
101111
110012
110113
111014
111115

2進数と10進数の変換についてですが、私たちが普段使っている10進数と考え方は同じです。
例えば、10進数の1234は、10の3乗×1 + 10の2乗×2 + 10の1乗×3 + 10の0乗 ×4 = 1000 + 200 + 30 + 4 = 1234です。
2進数もこの考え方に従うと、2進数の1111は、2の3乗×1 + 2の2乗×1 + 2の1乗×1 + 2の0乗×1 = 8 + 4 + 2 + 1 = 15です。
もう一つ2進数の例として、1010は、 2の3乗×1 + 2の2乗×0 + 2の1乗×1 + 2の0乗×0 = 8 + 0 + 2 + 0 = 10です。
このようにすると、2進数から10進数に変換することができます。

ここで、2進数の1111は、15であることがわかりました。この逆に、15は、1111であるということはどのようにしてわかるのでしょうか?
これは、15を2で割ります。
すると、7余り1になります。
7を2で割ります。
すると、3余り1になります。
3を2で割ります。
すると、1余り1になります。
1を2で割ります。
すると、0余り1になります。
この求めた余りを最後のものから順に並べていくと、1111となり、15は、2進数では、1111になることがわかります。

次に10進数の10は、2進数では、1010でした。
これは、10を2で割ります。
すると、5余り0です。
5を2で割ります。
すると、2余り1です。
2を2で割ります。
すると、1余り0です。
1を2で割ります。
すると、0余り1です。
この求めた余りを最後のものから順に並べていくと、1010となり、10は、2進数では、1010になることがわかります。

2進数と10進数の関係は、このようになっていますので、今後、変換するときに参考にしてください。

バイト

1バイトは、8桁のビットです。すなわち、1バイトは、8ビットにあたります。そして、1バイトは、2の8乗で、256種類です。

2バイトのshort型や、4バイトのint型は、それぞれ、16ビット、32ビットであり、short型は、2の16乗の、65536種類、int型は、2の32乗の、4294967296種類を表現できることになります。

データ量を表す単位

ハードディスクなどの記録媒体をGB(ギガバイト)、TB(テラバイト)などをよく見かけると思います。これらの単位について次の表で示します。

単位略称データ量
バイトB1B = 8b(ビット)
キロバイトKB1KB = 1024B
メガバイトMB1MB = 1024KB
ギガバイトGB1GB = 1024MB
テラバイトTB1TB = 1024GB

1000m = 1kmといった切りの良い単位という感じになりそうな感じがするのですが、1024という違和感がある数値になっています。
これは、コンピュータが0と1の2進数で表現されていることに関係します。1000は、10進数なら、10の3乗で表現されます。ただし、0と1の2進数しか扱えないコンピュータの場合、2進数に準じた形で表現できたほうが便利なのです。このため、10の3乗である1000は、2進数では、2の10乗の1024が1000に近く、2進数でも表現しやすいということで、1024倍となっています。

負数と2の補数

変数の型と数値の種類」にて、データ型の一覧でsignedとunsigendで値の範囲が違うことを学んだと思います。ただ、マイナスは、コンピュータではどのように扱うかをまだ、学んでいませんでしたので、ここどえ、負数について学びたいと思います。

データ型で範囲が狭いchar型を例に挙げて解説していきます。
char型のデータの範囲は、1バイト(8ビット)のため、2の8乗である256種類の表現ができますが、値の範囲は、-128~127の256種類になります。
この負数(マイナスの値)は、「2の補数」と言われている方法で表現します。

2の補数」とは、負の値を2進数で表現するために用いる方法で、2進数のビットを反転させて、1を足したものが2の補数になります。

コンピュータが負数を判断するのは、左端のビットが1の場合、負数となり、左端のビットが0の場合は、正数となります。
例えば、char型の8ビットが、10000000となっている場合
ビットを反転させると、01111111 となります。
さらに、1を足すと、10000000 となり、これを10進数に変換すると、128になります。このため、10000000は、-128となります。

次に、 char型の8ビットが、11111111となっている場合
ビットを反転させると、00000000 となります。
さらに、1を足すと、00000001 となり、これを10進数に変換すると、1になります。このため、11111111は、-1となります。

これにより、char型の正数の範囲は、ビットで表現すると、00000000~01111111となります。10進数に変換すると、0~127となります。
そして、char型の負数の範囲をビットで表現すると、10000000~11111111となります。10進数に変換すると、-128~-1となります。
この結果、char型の範囲は、-128~127となります。

-C言語