桁あふれ(オーバーフロー)とは何か?許容範囲の考え方を知る!

目安時間:約 6分

プログラマーを悩ませるもののひとつは、丸め誤差です。

 

そして、もうひとつ挙げるならば、「桁あふれ(オーバーフロー)」でしょう。

 

なぜ悩ませるのか?

 

なにかを計算する時には、本来は必ず、これらを意識する必要があるからです。

 

最近では、CPUの性能も上がっているため、一度に取り扱える数値も大きくなっています。よって、あまり、これらを意識することがない場面も多くなりました。

 

しかし、これらは、とても重要な考え方なのです。ここでそれを学んでください。

 

スポンサーリンク

 

桁あふれ(オーバーフロー)とは何か?

まず、丸め誤差については、丸め誤差とは何か?小数点以下の数値をどう扱うかを知る!で書いていますので、こちらを確認してみてください。

 

それでは、桁あふれとは何か?

それは、「扱える数値の許容範囲を超えた」ということなのです。

 

次に、その例を見ていきます。

 

 

桁あふれ(オーバーフロー)はどうのように起こるのか?

C言語の例として、2バイトの変数で考えてみましょう。

 

符号なし(unsigned short)と符号あり(short)変数に、それぞれ許容範囲の最大値とそれに1を加算した結果を確認する単純なプログラム(test1.c)を示します。

 

それでは、これを実行した結果ですが、以下のようになります。実行モジュールは、「test1」です。

 

スポンサーリンク

 

いかがでしょうか?

 

C言語では、標準出力(画面表示)を行う書式指定ができます。

符号なしの整数表示が「%u」、符号ありの整数表示が「%d」です。

 

(1)および(3)は、許容範囲の最大値の表示ですので、正しく表示されています。

 

しかし、(2)と(4)は、どこかおかしいです。

 

これが、桁あふれ、オーバーフローというものなのです。

 

 

まず、(2)ですが、65536を2進数で表記すると、

1 0000 0000 0000 0000(B)となり、17bitで表記されます。

 

1111 1111 1111 1111

+

1

で、1 0000 0000 0000 0000となり、

桁があふれているのです。

そして、変数は、2バイトですので、1bit目は無視され、残りの16bitの「0」が表示されているのです。

 

次に、(4)ですが、32768を2進数で表記すると、

1000 0000 0000 0000(B)となり、符号ビットである1ビット目にマイナスを表す「1」が立っています。

 

つまり、2bit目~16bit目までの15bitまでが許容範囲であるにもかかわらず、1bit目も必要となり、16bitで表記する必要があるわけです。

 

ですので、この場合も、桁が符号ビットにまで溢れているということになり、桁あふれになっていわけです。

 

単純に考えると、許容範囲の最大値+1は、許容範囲の最小値に戻るということになります。以下の許容範囲の数値を見ると、それを理解できると思います。

 

2バイトで許容される数値は、以下となります。

  • 符号なしの場合:0~65535(65536通りの数値)
  • 符号ありの場合:-32768~32767(65536通りの数値)

 

 

 

 

符号なしの場合

許容範囲の最大値(65535)に1を加えた「65536」を代入すると桁あふれが発生します。

65536を2進数で表すと、

1 0000 0000 0000 0000(B) で、17bit必要となり、16bitを超えるからです。

 

符号ありの場合

許容範囲の最大値(32767)に1を加えた「32768」を代入すると桁あふれが発生します。

32768を2進数で表すと、

1 000 0000 0000 0000(B) で、16bit必要となり、15bitを超えるからです。

 

 

桁あふれ、オーバーフローが発生すると、計算結果や条件文などに影響を及ぼします。特に、許容範囲を超えるか否かを設計の段階で確認し、超えるようであれば、さらに変数の型を拡張する必要があります。

 

整数型では、4バイト変数である「long型」、実数では、8バイト変数である「double型」を推奨します。

 

フラグなどで大きな値を扱わないようなケースでは、上記例のように2バイト変数を使用しても問題はありません。いずれにしても、変数の型をよく検討することが重要です。

 

スポンサーリンク


カテゴリ:プログラミング 

人気記事
プロフィール

こんにちは、管理人のあっきーです。

SE・プログラマになって30年の現役戦士です。

私が、30年のシステム開発経験で培ってきた困ったときの乗り越え方を教えます。

但し、対処法ではなく、私がお伝えするのは「思考法」です。

困ったときにこうすればよいという「行動」を教えても、その人にあうのかどうかはわかりません。ですから、「考え方」をお伝えするのです。

詳しいプロフィールは、
こちら。

最近の投稿
アーカイブ
カテゴリー
広告
ブログランキング参加しています。

ページの先頭へ