第1部 コンピュータの基礎
第2章 データの表現 — 2進数・文字コード・ビット
文字も、写真も、音楽も、コンピュータの中ではすべて「0と1の並び」でしかありません。なぜそうなるのか、そしてその0と1がどうやって文字や数に化けるのか。データ表現の土台を、順を追って解きほぐしていきましょう。ここを押さえると「文字化け」の正体まで見えてきます。
🎯 この章で学ぶこと
- コンピュータがすべてを0と1(ビット)で扱う理由
- ビットとバイトの関係、KB・MB・GB・TBという容量の単位
- 2進数・10進数・16進数の対応と、簡単な変換のやり方
- 負の数・小数がどう表され、なぜ計算に誤差が出るのか
- 文字コード(ASCII・Unicode・UTF-8)と、文字化けが起きる仕組み
2.1 コンピュータは0と1しか分からない
第1章で見たとおり、コンピュータは電気で動く機械です。その電気には、とてもシンプルな表現しかありません。ずばり「電気が流れているか(ON)/流れていないか(OFF)」の2つの状態だけです。この2状態を数字で書くと1(ON)と0(OFF)になります。これがすべての出発点です。
「たった2種類で足りるの?」と思うかもしれません。私たちが普段使う数字は0〜9の10種類(10進数)ですが、コンピュータはあえて0と1の2種類(2進数)だけを使います。理由は単純で、その方が壊れにくく、確実だからです。「電気がある/ない」なら多少の電圧のブレがあってもハッキリ区別できますが、「電圧を10段階に細かく分ける」やり方だと、わずかなノイズで隣の値と混同してしまいます。信頼性を最優先した結果が、0と1の世界なのです。
この0か1か、1つ分の情報の最小単位をビット(bit)と呼びます。「binary digit(2進の桁)」を縮めた言葉です。電球1個の点いた/消えたが1ビット、と考えると分かりやすいでしょう。コンピュータの中では、この電球が何十億個も並んで、あらゆる情報を表現しています。
2.2 ビットとバイト、そして容量の単位
1ビット(電球1個)では、0か1の2通りしか表せません。これでは「あ」1文字すら表現できません。そこで、ビットを8個まとめて1つの単位にします。これがバイト(byte)です。
1バイト = 8ビット。8個の電球それぞれが0/1を取れるので、組み合わせは 2×2×2×2×2×2×2×2 = 256通りになります。この256通りがあれば、アルファベットや数字、記号をひととおり表現できます。バイトはコンピュータがデータを扱うときの基本のかたまりで、「1文字」「1つの色」などの単位としてよく登場します。
| まとまり | ビット数 | 表せる組み合わせ |
|---|---|---|
| 1ビット | 1 | 2通り |
| 2ビット | 2 | 4通り |
| 4ビット | 4 | 16通り |
| 1バイト | 8 | 256通り |
ファイルの大きさやストレージの容量は、このバイトを基準に数えます。ただしバイトは小さすぎるので、大きな数をまとめる接頭辞(K・M・G・T)を付けて表します。
| 単位 | 読み | おおよその大きさ | 身近な例 |
|---|---|---|---|
| B(バイト) | バイト | 1文字ぶん程度 | 半角文字1つ |
| KB(キロバイト) | キロ | 約1,000バイト | 短いテキスト文書 |
| MB(メガバイト) | メガ | 約100万バイト | 写真1枚、音楽1曲 |
| GB(ギガバイト) | ギガ | 約10億バイト | 映画1本、スマホの空き容量 |
| TB(テラバイト) | テラ | 約1兆バイト | パソコンのストレージ全体 |
単位が1つ上がるごとに約1,000倍(正確には後述のとおり1,024倍)になります。「4GBのメモリ」「512GBのSSD」「1TBのバックアップ」といった表記も、この階段のどこかを指しているにすぎません。
コンピュータは2進数の世界なので、実は 2 を10回かけた 1,024(=2の10乗)というキリのいい数で区切るのが自然です。そのため長らく「1KB=1,024バイト」と扱われてきました。一方、一般的な「キロ=1,000」との混同を避けるため、1,024倍のときはKiB(キビバイト)・MiB(メビバイト)・GiB(ギビバイト)という2進接頭辞を使う流儀もあります。ストレージの箱には「1TB=1,000,000,000,000バイト」と1,000区切りで書かれているのに、パソコンで見ると容量が少し小さく表示されるのは、OS側が1,024区切り(TiB)で計算しているためです。「容量が減っている!」と焦る必要はありません。数え方の違いです。
2.3 2進数のしくみ
私たちが普段使う10進数は、0から9まで数えて、次で桁が上がります(9→10)。各桁は右から順に「1の位、10の位、100の位……」と10倍ずつ重みが増えていきます。
2進数もまったく同じ考え方で、違いは「使える数字が0と1だけ」「桁の重みが2倍ずつ」という点だけです。右から順に「1の位、2の位、4の位、8の位……」と増えていきます。たとえば2進数の 1011 は次のように計算します。
| 桁の重み | 8 | 4 | 2 | 1 |
|---|---|---|---|---|
| 2進数 | 1 | 0 | 1 | 1 |
| 計算 | 8×1 | 4×0 | 2×1 | 1×1 |
合計すると 8 + 0 + 2 + 1 = 11。つまり2進数の 1011 は10進数の 11 です。「重みのある桁のうち、1が立っているところを足す」——これだけで2進数は読めます。次の対応表を眺めると、0と1の並びが数として動いていく様子がつかめます。
| 10進 | 2進(4桁) | 16進 |
|---|---|---|
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| 2 | 0010 | 2 |
| 3 | 0011 | 3 |
| 4 | 0100 | 4 |
| 5 | 0101 | 5 |
| 6 | 0110 | 6 |
| 7 | 0111 | 7 |
| 8 | 1000 | 8 |
| 9 | 1001 | 9 |
| 10 | 1010 | A |
| 11 | 1011 | B |
| 12 | 1100 | C |
| 13 | 1101 | D |
| 14 | 1110 | E |
| 15 | 1111 | F |
逆に「10進数を2進数に直す」ときは、2で割った余りを下から並べるのが定番のやり方です。13を例にやってみましょう。
13 ÷ 2 = 6 余り 1 ↑ここから下から上へ読む
6 ÷ 2 = 3 余り 0
3 ÷ 2 = 1 余り 1
1 ÷ 2 = 0 余り 1
余りを下から上へ並べる → 1101
よって 13(10進) = 1101(2進)
2進数では 2の累乗がキリのいい数になります。2=10、4=100、8=1000、16=10000……というように、1のうしろに0が並ぶ形です。ネットワークで出てくる「256」「1024」や、色の「256階調」なども、すべてこの2の累乗です(256=2の8乗)。この感覚があると、後の章のIPアドレスやサブネット(第9章)の話がぐっと楽になります。
2.4 16進数はなぜ使うのか
2進数はコンピュータには自然でも、人間が読むにはつらいものです。たとえば1バイト(8ビット)を 11010110 と書かれても、パッと読めませんし、書き写すときに0と1を数え間違えそうです。そこで登場するのが16進数です。
16進数は0〜9のあとにA〜Fを足して、16種類の数字で1桁を表します(A=10、B=11、……、F=15)。ここがポイントで、16は2の4乗なので、2進数の4桁がちょうど16進数の1桁に対応します。先ほどの 11010110 を4桁ずつ区切ると、1101 と 0110。対応表を見れば 1101=D、0110=6 なので、まとめて D6 と書けます。8桁が2桁になり、ぐっと読みやすくなりました。
| 2進数(8桁) | 1101 | 0110 |
|---|---|---|
| 16進数(2桁) | D | 6 |
この「短く書ける・2進数と相互変換しやすい」という性質のおかげで、16進数はコンピュータの現場のあちこちで使われています。IT部門でよく目にするのは次のような場面です。
| 登場する場所 | 例 | 意味 |
|---|---|---|
| Webの色コード | #FF0000 | 赤・緑・青を各1バイト(00〜FF)で指定。これは真っ赤 |
| MACアドレス | 00:1A:2B:3C:4D:5E | ネットワーク機器を識別する番号(第8章) |
| 文字コード | U+3042 | Unicodeで「あ」を指す番号 |
| メモリのアドレス | 0x7FFE0000 | メモリ上の位置。0xは「これは16進」の目印 |
#FF0000 を例に見てみましょう。頭の # のあと、2桁ずつで赤(FF)・緑(00)・青(00)の強さを表します。FF は16進で最大の255、00 は最小の0。つまり「赤が全開、緑と青はゼロ」なので真っ赤になる、というわけです。白は #FFFFFF(全色全開)、黒は #000000(全色ゼロ)です。色の指定に16進が使われる理由が、これで腑に落ちるはずです。
エラーメッセージやログに 0x1F4 のような値が出てくると身構えてしまいますが、0x は単に「このあとは16進数ですよ」という目印にすぎません。中身は普通の数です(0x1F4 は10進の500)。ログの読解では、この「16進のクセ」に慣れているだけで落ち着いて対処できます。
2.5 負の数・小数はどう表すのか
ここまでは0以上の整数(0、1、2……)の話でした。では、マイナスの数や小数点の付いた数は、0と1だけの世界でどう表すのでしょうか。仕組みの細部までは覚えなくて大丈夫ですが、「考え方」と「そこから生まれる注意点」だけは知っておくと実務で役立ちます。
負の数 — 「補数」という発想
マイナス記号そのものは0と1では書けません。そこでコンピュータは補数(ほすう)という巧妙な方法を使います。ざっくり言うと、「引き算を足し算で済ませるための表現」です。たとえば時計で「3時間戻す」ことを「9時間進める」で代用できるのと似た発想で、ある数を『あとどれだけ足せば桁があふれてゼロに戻るか』でマイナスを表します。おかげでコンピュータは引き算専用の回路を持たなくてよく、足し算の回路だけで引き算までこなせます。詳しい計算方法は覚えなくてかまいません。「マイナスも0と1の並びだけで、しかも足し算の仕組みで扱えるよう工夫されている」——これがつかめれば十分です。
小数 — 「浮動小数点数」と、避けられない誤差
小数(3.14 など)は浮動小数点数という形式で表します。これは「有効数字」と「小数点の位置(何桁ずらすか)」を分けて記録するやり方で、科学で使う 3.14 × 10の2乗 のような表記のコンピュータ版だと思ってください。とても広い範囲の数を表せる便利な方法です。
ただし、ここに実務で必ず知っておくべき落とし穴があります。2進数では、10進のキリのいい小数がぴったり表せないことがあるのです。代表例が 0.1 です。10進では単純な 0.1 も、2進数に直すと 0.000110011001100… と無限に続いてしまい、どこかで打ち切るしかありません。その結果、ごくわずかな誤差が残ります。実際に計算させると、こうなります。
>>> 0.1 + 0.2
0.30000000000000004
0.3 になってほしいのに、末尾にゴミのような数字が付いています。これはバグではなく、2進数で小数を扱う以上、原理的に避けられない現象です。どんなプログラミング言語でも同じことが起こります。
この誤差は、金額や個数のように「1円のズレも許されない」計算で問題になります。合計が1円合わない、といったトラブルの原因はこれであることが多いです。実務では、金額は「円」ではなく「銭」や最小単位の整数で持つ、あるいは誤差の出ない専用のしくみ(たとえばデータベースの DECIMAL 型や、プログラミング言語の10進専用の型)を使う、といった対策をとります。「小数の計算はわずかにズレることがある」と頭の片隅に置いておくだけで、原因不明のトラブルを一歩早く見抜けます。
2.6 文字コード — 文字化けの正体
コンピュータは数しか扱えないので、文字も「番号」に置き換えて記憶します。「どの文字に何番を割り当てるか」を決めた対応表が文字コードです。この対応表がずれると、あの見慣れた「文字化け」が起こります。歴史を追うと、その理由がよく分かります。
ASCII — 英語の世界の共通ルール
最初に広く使われたのがASCII(アスキー)です。1バイト(の下位7ビット)で、アルファベットの大文字・小文字、数字、基本的な記号など128種類を表します。たとえば A=65、a=97、0(文字のゼロ)=48、といった具合です。英語圏ではこれで足りましたが、128種類では日本語のひらがな・カタカナ・漢字はとても収まりません。
日本語の混乱期 — Shift_JISやEUC-JP
そこで各国が独自に文字コードを作りました。日本ではShift_JISやEUC-JPなどが使われ、1文字を2バイトで表して漢字を収めました。ところが「同じ番号でも、どの文字コードで読むかによって別の文字に見える」ため、送り手と受け手で解釈がずれると文字化けが発生します。これが、いわゆる文字化けの正体です。
Unicode と UTF-8 — 世界の文字を1つの表に
この混乱を解消するために生まれたのがUnicode(ユニコード)です。世界中のあらゆる文字に、国をまたいで通し番号を振る壮大な取り組みで、日本語も絵文字もここに含まれます。「あ」には U+3042 という番号が割り当てられています。
そのUnicodeの番号を、実際にバイトの並びとしてどう保存するかを決めた方式がUTF-8です。UTF-8はASCIIと互換があり(英数字は従来どおり1バイト)、日本語などは3バイト前後で表します。無駄が少なく世界中で扱えるため、今ではWebページやファイルの事実上の標準になっています。迷ったらUTF-8、というのが現在の基本です。
| 文字コード | 扱える文字 | 今の立ち位置 |
|---|---|---|
| ASCII | 英数字・記号(128種) | UTF-8の一部として今も生きている |
| Shift_JIS | 日本語(2バイト) | 古いWindowsソフトやCSVで今も遭遇する |
| EUC-JP | 日本語(2バイト) | 古いUNIX系システムで見かける |
| UTF-8 | 世界中の文字・絵文字 | 現在の標準。まずこれ |
改行コード — 目に見えない厄介者(CR / LF / CRLF)
文字コードとあわせて知っておきたいのが改行コードです。「行の終わり(改行)」も、実は目に見えない特別な文字として記録されており、その表し方がOSごとに違います。
| 改行コード | 表記 | 主に使うOS |
|---|---|---|
| LF | \n | macOS(現行)・Linux |
| CR | \r | 昔のMac(今はまれ) |
| CRLF | \r\n | Windows |
改行コードが食い違うと、「テキストファイルを開いたら全部が1行になってしまった」「行末に ^M のような謎の記号が付く」といった現象が起きます。WindowsとLinuxの間でファイルをやり取りするときに、よく問題になるポイントです。
UTF-8のファイルには、先頭にBOM(Byte Order Mark)という「これはUTF-8ですよ」という目印の3バイトが付いていることがあります。人の目には見えませんが、これがあるとプログラムによっては1行目の先頭に謎の文字が混ざったように扱われ、CSVの1列目のヘッダー名が一致しない、といったトラブルを起こします。「見た目は同じなのに、なぜか1列目だけ処理が失敗する」ときは、BOMの有無を疑ってみてください。多くのエディタは「UTF-8」と「UTF-8(BOM付き)」を選び分けられます。
文字コードは、単なる「文字化け」で済まない場面があります。たとえば、他システムから受け取ったCSVをShift_JISのつもりで開いたのに実はUTF-8だった(あるいはその逆)、というだけで、取り込みが丸ごと失敗したり、顧客名が全件文字化けして基幹システムに登録されたりします。システム間のデータ連携では、「どの文字コードで、どの改行コードでやり取りするか」を最初に取り決めておくことが、地味ですが極めて重要です。
入門コース(Python)でファイルを開くとき、わざわざ encoding="utf-8" と明示するよう教えたのも同じ理由です。OSやツールが勝手に選ぶ「なんとなくの文字コード」に任せると、開発環境では動いたのに本番の別サーバーで文字化けする、といった再現しにくい事故につながります。文字コードを明示的に指定することは、トラブルを未然に防ぐ立派なセキュリティ・運用習慣なのです。この「あいまいさを残さない」姿勢は、第2部のターミナル操作でも一貫して大切になります。
まとめ
- コンピュータは電気のON/OFF、つまり0と1(ビット)だけで情報を扱う。2種類にするのは確実で壊れにくいから
- 8ビット=1バイトで256通り。容量はB→KB→MB→GB→TBと約1,024倍ずつ上がる
- 2進数は「桁の重みが2倍ずつ」。1が立った桁の重みを足せば読める
- 16進数は2進4桁を1桁にまとめた表記。色コードやMACアドレス、ログでよく出会う
- 負の数は補数、小数は浮動小数点数で表す。0.1のような小数はわずかに誤差が出るので、金額計算は整数か専用の型で扱う
- 文字コードはASCII→各国独自→Unicode/UTF-8と発展。標準はUTF-8。文字化け・改行コード・BOMは連携トラブルの原因になりやすい
練習問題
次の2つを計算してください。(1)2進数の 101010 は10進数でいくつですか。(2)10進数の 25 を2進数に直すといくつですか。
解答を見る
(1) 42 です。桁の重みは右から 1・2・4・8・16・32。1が立っているのは 32・8・2 の桁なので、32 + 8 + 2 = 42。
(2) 11001 です。25を2で割り続けて余りを下から並べます。25÷2=12余り1、12÷2=6余り0、6÷2=3余り0、3÷2=1余り1、1÷2=0余り1。下から読んで 11001。検算すると 16 + 8 + 1 = 25 で一致します。
「1枚あたり約2MBの写真を、8GBのUSBメモリに保存したい。ざっくり何枚くらい入りますか?」と聞かれました。おおよその枚数と、その計算の考え方を説明してください。
解答を見る
おおよそ4,000枚です。単位を1つそろえて考えます。1GB=約1,000MBなので、8GB=約8,000MB。これを写真1枚2MBで割ると、8,000 ÷ 2 = 4,000枚。実際にはOSの管理領域などで使える容量は少し減るため「3,000〜4,000枚くらい」と幅を持たせて答えると親切です。ポイントは「まず単位をMBかGBのどちらかにそろえてから割り算する」ことです。
取引先から届いたCSVファイルを表計算ソフトで開いたら、日本語の項目名がすべて「�」や意味不明な記号に化けていました。考えられる原因と、確認・対処の方向性を述べてください。
解答を見る
最も疑わしいのは文字コードの不一致です。ファイルはUTF-8で保存されているのに、ソフトがShift_JISとして開いた(またはその逆)場合、番号の解釈がずれて文字化けします。対処としては、(1)エディタや表計算ソフトの「文字コードを指定して開き直す」機能でUTF-8とShift_JISを切り替えて試す、(2)送り手に「どの文字コードで出力したか」を確認する、といった方向で切り分けます。あわせて、1列目だけおかしい場合はBOMの影響、行が変にくっつく・分かれる場合は改行コードの違いも疑います。根本策は、連携の取り決めとして文字コードと改行コードを事前に統一しておくことです。