中級では文字集合と符号化・圧縮を見ました。上級では、負の数・小数・文字・バイトの並びを、実際のビットがどう表しているかへ踏み込みます。メディアの種類・圧縮の使い分けは データの正体 を参照してください。
上級の解説は準備中のため、上級の内容を表示しています。
概要 — まず全体をつかむ
詳細 — 1段階ずつ追う
なぜ0と1なのか、を情報量で捉え直す
「2値が確実だから」の裏には、ノイズマージンという考え方があります。信号は必ず揺れますが、判定のしきい値から遠い2点(低い=0・高い=1)だけを使えば、多少揺れても誤読しません。10段階の電圧なら隣との差が狭く、同じノイズで誤りが増えます。確実さと引き換えに1本あたりの情報を1ビットに絞る——これが2進の設計思想です。
1ビットは「不確かさを半分にする」情報量です。だからnビットで2のn乗通りを区別でき、束ねるほど表現力が指数的に増えます。
アニメーション『ビット=スイッチのオン/オフ』を開く
数の表現の深部
同じビット列でも、解釈の規則を変えると別の数になります。
2の補数(負の整数)。負数は「全ビット反転して1を足す」で作ります。こうすると引き算を足し算の回路で処理でき、符号ごとの特別扱いが要りません。8ビットなら -128〜127、桁あふれ(※1 オーバーフロー)は最上位からあふれたぶんを捨てる「ラップアラウンド」が既定です。127に1を足すと-128に回り込むのはこのためです。
浮動小数点(IEEE 754)。実数は符号・指数・仮数(※2 仮数)の3部で近似します。単精度なら符号1ビット・指数8ビット・仮数23ビット。値は「符号 × 1.仮数 × 2の指数乗」の形で、先頭の1は省く(ケチ表現)ぶん1ビット得します。ここで宿命なのが丸め誤差です。0.1は2進では循環小数(0.0001100110011…)になり、有限桁では正確に表せません。だから0.1+0.2がぴたり0.3にならないことがあります。
登場人物メモ:
- ※1 オーバーフロー — 表せる桁を超えてあふれること。ラップ(回り込み)と飽和(上限で止める)の扱いがある
- ※2 仮数 — 有効数字にあたる部分。ここの桁数が「どこまで細かく表せるか」を決める
金額のように誤差が許されない計算は、浮動小数点を避けて整数(最小単位=円や銭)や10進型で扱うのが定石です。
アニメーション『0と1の解釈(数・文字・色)』を開く
文字コードの深部
文字は「番号を振る」層と「バイトにする」層に分かれます。
- ASCII — 英数字・記号を7ビット(0〜127)に割り当てた古典。1バイトに収まる
- Unicode — 世界の文字に符号位置(コードポイント)を与える台帳。「あ」は U+3042
- UTF-8 — その符号位置を可変長でバイト化する規則。ASCII範囲は1バイト・多くの日本語は3バイト・絵文字は4バイト
UTF-8の妙は、先頭バイトのビットパターンで「この文字は何バイトか」が分かる自己同期性にあります。だから途中から読んでも文字境界を復元でき、ASCIIとも互換です。「見た目1文字(書記素)」が複数の符号位置をZWJで結合していることもあり、バイト数・符号位置数・書記素数は一致しません。関連は data-basics で深掘りしています。
バイトの並びとビット操作
エンディアン。2バイト以上の数値をメモリに置くとき、どのバイトを先頭(低位アドレス)に置くかで2流派があります。
- リトルエンディアン — 最下位バイトを先頭に(x86系が採用)
- ビッグエンディアン — 最上位バイトを先頭に(ネットワークバイトオーダ)
ファイルやネットワークでバイト列をやり取りするとき、送り手と受け手のエンディアンが食い違うと数値が化けます。だから通信では並びを規約で固定します。
ビット演算。ビットを直接操る道具です。AND(両方1で1)・OR(どちらか1で1)・XOR(異なれば1)・NOT(反転)に、左右のシフトを加えたもの。フラグの集合を1バイトに詰めてANDで判定する、シフトで2倍・半分にする、XORで簡単な入れ替えをする——低レベルではこうした操作が頻出します。CPU内部でどう実行されるかは cpu を参照してください。
⚠️ 深部の落とし穴
- 浮動小数点の等値比較 —
0.1 + 0.2 == 0.3が偽になりうる。差の絶対値がしきい値未満か、で比べる - 整数オーバーフロー — 上限を超えて回り込み、正の値が突然負になる。境界値のテストが要る
- 符号化の取り違え — UTF-8で書いたものを別方式で読むと文字化け。保存と読込の規則を一致させる
- エンディアン依存 — 生のバイト列を無検査で数値にすると、環境が変わって化ける
関連する知識
理解度チェック
そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。
問1. 8ビットの符号つき整数(2の補数)が表せる範囲はどれ?
問2. リトルエンディアンの説明として正しいのは?
問3. IEEE 754 単精度(32ビット)の内訳として正しいのは?
問4. 0.1 + 0.2 == 0.3 が偽になりうる根本的な理由はどれ?
問5. UTF-8の説明として正しいのはどれ?
問6. 金額のように誤差が許されない計算で、本文が勧める扱い方はどれ?
問7. 2つのビットが異なるとき1、同じとき0になるビット演算を英字3文字で答えてください。
問8. 多バイト数値の最上位バイトを先頭(低位アドレス)に置く並び順で、ネットワークで慣習的に使われるものを何エンディアンと呼ぶ?