#04 バイナリデータ入門

整数の足し算と桁溢れ(オーバーフロー)

時計は24時になったら0時に戻る

時計の針を思い浮かべてください。23時の1時間後は24時ではなく、0時(深夜) に戻ります。これは「24を超えたら0に戻る」という決まりがあるからです。

コンピュータの整数演算でも、まったく同じことが起こります。

8ビットの整数で表せる最大値は 255 です。255の次は256ではなく、0に戻ってしまいます。この現象を 桁溢れ(オーバーフロー) と言います。


8ビットで表せる最大値

8ビット(1バイト)の整数で表せる値の範囲を確認しましょう。

最小値:00000000 = 0
最大値:11111111 = 255

最大値の11111111(2進数)を10進数に変換すると:

128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255

つまり 8ビット = 256種類の値(0〜255) しか表せません。


255 + 1 = 0 になるしくみ

8ビットで「255 + 1」を計算してみましょう。2進数で書くと:

  1 1 1 1 1 1 1 1   (= 255)
+ 0 0 0 0 0 0 0 1   (= 1)
-------------------
1 0 0 0 0 0 0 0 0   (= 256)

9ビット目に繰り上がり!

足し算の結果は9ビットの 100000000 (= 256) になります。しかし8ビットの変数には 8ビット分しか入りません。あふれた9ビット目は捨てられてしまいます。

1 0 0 0 0 0 0 0 0
↑これが捨てられる
  0 0 0 0 0 0 0 0  ← 残るのはここだけ

結果:00000000 = 0

これが オーバーフロー(桁溢れ) です。


バイナリ加算の仕組み(繰り上がり)

2進数の足し算のルールはシンプルです。

0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 10  (0を書いて1を繰り上げ)

具体的に「200 + 100」を8ビットで計算してみます。

  1 1 0 0 1 0 0 0   (= 200)
+ 0 1 1 0 0 1 0 0   (= 100)
-------------------
1 0 0 1 0 1 1 0 0   (= 300)

9ビット目があふれる → 捨てられる

残り:0 0 1 0 1 1 0 0 = 44

200 + 100 = 300 のはずが、8ビットでは 44 になってしまいます。


日常で起きる「繰り上がりのリセット」

時計以外にも、「最大値を超えると0に戻る」現象は日常に意外と多くあります。

走行距離計(オドメーター) 古い車のメーターは 99999 km の次が 00000 に戻ります。

カレンダーの月 12月の次は1月に戻ります。

ゲームのスコア 古いゲーム機では得点が最大値を超えると0に戻るものがありました(スコアカウンター問題)。

これらはすべて「一定の範囲で値が循環する」という点でオーバーフローと同じ発想です。数学的には 剰余(mod)演算 と呼ばれます。

(255 + 1)  mod 256 = 0
(200 + 100) mod 256 = 44

実際に起きたバグの例

ゲームの年齢計算バグ

あるゲームでは、プレイヤーの年齢を8ビット符号なし整数で管理していました。

255歳のキャラクターが誕生日を迎える
→ 255 + 1 = 256 → オーバーフローで 0 歳になった
→ 突然赤ちゃんになった

累計スコアのリセット

シューティングゲームのスコアを16ビット(最大65535点)で管理していたところ:

65535点 + 1点 = 0点
→ 上級者ほどスコアがリセットされた

実際に1980年代のゲームでこの問題が起きており、「スコアのカウンターストップ」として有名です。

年2000年問題(Y2K)

厳密にはオーバーフローとは少し違いますが、「西暦を下2桁だけで管理していたら2000年が00年になった」という問題も、データの桁数不足が原因でした。


ビット数ごとの最大値

用途に応じて、コンピュータは異なるビット数の整数型を使います。

ビット数最大値計算式
8ビット2552⁸ − 1
16ビット65,5352¹⁶ − 1
32ビット4,294,967,295(約43億)2³² − 1
64ビット18,446,744,073,709,551,615(約1844京)2⁶⁴ − 1

これらはすべて「符号なし整数(0以上の整数だけ)」の場合です。マイナスも扱う「符号付き整数」については次回詳しく説明します。

実用的な目安:

  • 8ビット … 色のRGB値、1バイトのデータ
  • 16ビット … 音声サンプル、古いゲームのスコア
  • 32ビット … 一般的な整数演算(多くの言語のデフォルト)
  • 64ビット … ファイルサイズ、現代の主力整数型

オーバーフローを防ぐには

1. 十分なビット数を選ぶ

扱う値の最大値がわかっているなら、それを超えないビット数を選びます。人口を扱うなら32ビット(約43億)で十分ですが、巨大な金融計算には64ビットが必要です。

2. オーバーフローを検出する

プログラミング言語によっては、オーバーフローが起きたときに エラーを発生させる 機能があります。この設定を活用することで、静かにバグが起きる状況を防げます。

3. 飽和演算(サチュレーション)

最大値を超えたら最大値のままにする(増えない)方法です。画像処理などで使われます。

通常のオーバーフロー:255 + 1 = 0
飽和演算:           255 + 1 = 255(これ以上増えない)

まとめ

  • 8ビット整数で表せる最大値は 255(11111111)
  • 255 + 1 = 256 は9ビット必要なため、8ビットでは 0 に戻る
  • これが「桁溢れ(オーバーフロー)」
  • 2進数の足し算は繰り上がりの連鎖で計算される
  • ビット数ごとに最大値が決まっており、超えると値がループする
  • 実際のプログラムでもオーバーフローによるバグが起きてきた

次回は「マイナスの数をどうやってビットで表現するか」、2の補数 を学びます。