定義
整数オーバーフロー(Integer Overflow)とは、コンピューターが数値を保存するために割り当てたメモリ枠の最大値を超えた際に発生する計算エラーです。収まりきらなくなった瞬間、数値がまったく意図しない値(多くは負の数やゼロ)に切り替わってしまいます。
車のメーターが9999から0000に戻る理由
走行距離を表示するアナログのメーター(オドメーター)を思い浮かべてみてください。4桁を表示できるメーターは、最大でも「9999」までしか記録できません。
ここでさらに1km走っても、メーターは「10000」を表示できません。5桁目を記録する物理的なスペースがないため、あふれた先頭の1は消えてしまい、結果的に0000に戻ってしまうのです。
コンピューターの内部でも、まったく同じ原理が働いています。コンピューターは数値を記録するとき、メモリ空間のサイズをあらかじめ決めています。8個、32個、64個のように、決められた数のビット(0と1を収める箱)を使います。その箱を1でいっぱいに満たした状態でさらに数値を1足すと、桁があふれ出し、コンピューターは一番上の桁を切り捨ててしまいます。
もう少し詳しく:なぜ突然マイナスになるのか?
単にゼロに戻るよりも、プログラミングの世界でさらに頻繁に起こり危険なのが、プラスの数が突然巨大なマイナスの数へと反転する現象です。
もう少し詳しく言うと、コンピューターは正の数と負の数の両方を扱うために、数値の一番左にある1ビットを「符号表示用」として使います。このビットが0なら正の数、1なら負の数を表します。
例えば、32ビット整数で表現できる最大の正の数は、約21億(2,147,483,647)です。ここに1を足すと、数値が21億1になるのではなく、ビット計算のルールによって先頭の符号ビットが0から1へと切り替わってしまいます。多くのコンピューターは「2の補数」という表現形式を採用しているため、先頭ビットが1になると約-21億(-2³¹)という巨大な負の値を加算した状態になります。その結果、コンピューターはこの値を約マイナス21億として誤って読み取ってしまうのです。ゲームで体力を増やしすぎて上限を超えた途端にキャラクターが即死したり、銀行口座にお金を預けたのに借金まみれになったりする不条理なバグは、まさにここから生まれます。
現実世界を揺るがしたオーバーフロー事件
この現象は、教科書の中だけの話ではありません。実際に数多くのサービスや現実世界を大混乱に陥れた歴史的な事件が数多く存在します。
もっとも有名なのが、YouTubeの『江南(カンナム)スタイル』再生回数事件です。YouTubeは当初、再生回数を記録する変数に32ビット符号付き整数(最大約21億)を使用していました。しかし、PSYの『江南スタイル』のミュージックビデオが世界的な大ヒットとなり上限に迫ったため、YouTubeのエンジニアは上限を超える数か月前に前もって64ビット整数へと記録形式を移行し、上限を約922京回へと引き上げました。2014年12月にYouTubeがこの裏話をユーモアを交えて明かしたことで広く知られるようになりました。
より深刻な大惨事も起きています。1996年、巨額の費用を投じて打ち上げられたヨーロッパの宇宙ロケット「アリアン5」は、打ち上げからわずか約40秒で空中で爆発・崩壊しました。水平速度に関するデータ(64ビット浮動小数点数)を16ビット符号付き整数へと変換する際にオーバーフローが発生して慣性基準システムが停止し、フライトコンピューターがそのエラー信号を正規の飛行データと誤認してロケットが飛行経路を外れたことが原因でした。
よくある誤解
数値が上限を超えた場合、コンピューターは即座にエラーメッセージを表示して安全に停止する。
C言語やC++などの言語では、エラーを出さずに値が一周して循環したり(符号なし整数の場合)、動作が未定義(符号付き整数の場合)になったりします。そのため事前にバグを発見するのが非常に難しく危険です。一方でSwiftのようにオーバーフローを検知して即座にプログラムを停止させる言語や、Rustのようにデバッグビルドでは停止するものの標準のリリースビルドでは値が一周して循環する言語もあります。
日常で出会う場面
YouTubeの再生回数が32ビットの上限(約21億回)に近づいたため、事前に64ビットへと拡張したエピソード。
ゲームで所持金が上限を超えた瞬間に突然0ゴールドになったり、マイナス表示(借金状態)になったりするバグ。
宇宙ロケット「アリアン5」が、速度データを16ビット整数に変換する際にオーバーフローを起こし、航法装置が停止して爆発した事故。
つまり ひとことで
コンピューターが決めた数値の枠(上限)を超えた際、数値が意図しない値(負の数やゼロなど)にひっくり返ってしまう計算エラーのことです。