- ベストアンサー
変数の大きさを超える代入
現在作っているプログラムで、一定時間ごとに変数に一定値が 加算され続けるような場所があります。 基本的にはint型の最大値を超えることはまずないのですが、 C言語やC++でたとえばint型で宣言した変数に対し、x++; のように一定周期ごとに記述して加算してゆき、最大値である、 +2147483647を超えた場合、xには何が代入されているんでしょうか。 -2147483648~+2147483647が範囲ですから、一周して、 最低値である-2147483648に加算されてゆくことになるのでしょうか? それとも、超えることが予想される場合、最大値を超えたら0にするなど 明示的に何らかの対処をしたほうがよいのでしょうか。 プログラム的には中身の数値に関してはあまり関係ないので、 その変数型の範囲で不可なく動作するなら問題ありません。 超えることが予想される場合、対処するべきなのか、 放っておいてもよいのかどうかを教えていただきたいです。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
実験して調べて見るのが近道でしょう。 C言語を調べると「負数は2の補数で表すとは限らない」となっているので、予想通りにはならないかも知れません。 でも、あなたの予想通りになるんじゃないかな。 ソフトでも何でも、まずは基本が動く事。次にエラー対処の仕様をどのようにするかがポイントです。 この場合は最大値で保持するのが良いでしょう。更にその後ディクリメントが有っても最大値を保持したままにするとか。 そのような仕様を抜け目無く考えるのが大変なんですよ。
その他の回答 (4)
- jacta
- ベストアンサー率26% (845/3158)
> あっているでしょうか? あっているかどうかは、処理系を特定しなければ何ともいえません。 もっと具体的にいうと... 1バイト=8ビットの処理系で、1バイトの整数値について考えた場合、-127の内部表現は次の3種類があります。 10000000 (1の補数表現) 10000001 (2の補数表現) 11111111 (符号ビットと絶対値) さらに、オーバーフローが発生すると例外(C++の例外ではなくハードウェア的なもの)が発生する処理系もあります。 これらを考えると、どうなるかは一概にはいえないことが分かるはずです。
- pyonmae
- ベストアンサー率64% (40/62)
こんにちは。 プログラムの動作としては、既に回答が出ている通りです。 「数値の動作」に的を絞ってご質問に答えるとするならば、 >一周して、最低値である-2147483648に加算されてゆくことになるのでしょうか? これはYesです。 ただ、「一周」という表現が少し引っかかるのですが、補数表現に対するご認識は大丈夫でしょうか。 >超えることが予想される場合、対処するべきなのか、 絶対に対処するべきです。 ただ、最大値を超えたら0にする、よりは、最大値を超えそうになったら最大値をキープするようにした方が何となく自然かなという気がします。(もちろん、開発しているソフトの仕様によりますが)
- jacta
- ベストアンサー率26% (845/3158)
符号付き整数のオーバーフローは未定義の動作になります。 処理系不明の状況では、具体的にどう振る舞うかは予測不能だと考えてください。
- Tasuke22
- ベストアンサー率33% (1799/5383)
オーバーフローは割り込み対象です。 ただマスク出来るので無視したら、+1を続けると 最大値からマイナスの最小値になると思います。 マスクしなければ、ゼロ割のようにプログラムは 落ちます。
お礼
みなさん解答ありがとうございました。 一応対処事態はしていたのですが、その処理しなかった場合、 どのような動作を起こすのかただ気になりましたので 質問させていただきました。 >一周して、補数表現 たとえば1バイトで一番左を符号として考えるなら、 10進数で+127は01111111、-127は10000000などということですよね? なんとなくイメージ的に周回してると捉えていただけです(^^;) 最大値を超えるというのは、01111111+1などを考えると、 10000000となるので、最低値の-127になると考えていたのですが、 あっているでしょうか?