• ベストアンサー

変数の大きさを超える代入

現在作っているプログラムで、一定時間ごとに変数に一定値が 加算され続けるような場所があります。 基本的にはint型の最大値を超えることはまずないのですが、 C言語やC++でたとえばint型で宣言した変数に対し、x++; のように一定周期ごとに記述して加算してゆき、最大値である、 +2147483647を超えた場合、xには何が代入されているんでしょうか。 -2147483648~+2147483647が範囲ですから、一周して、 最低値である-2147483648に加算されてゆくことになるのでしょうか? それとも、超えることが予想される場合、最大値を超えたら0にするなど 明示的に何らかの対処をしたほうがよいのでしょうか。 プログラム的には中身の数値に関してはあまり関係ないので、 その変数型の範囲で不可なく動作するなら問題ありません。 超えることが予想される場合、対処するべきなのか、 放っておいてもよいのかどうかを教えていただきたいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • ricardo_
  • ベストアンサー率19% (14/72)
回答No.5

 実験して調べて見るのが近道でしょう。  C言語を調べると「負数は2の補数で表すとは限らない」となっているので、予想通りにはならないかも知れません。  でも、あなたの予想通りになるんじゃないかな。  ソフトでも何でも、まずは基本が動く事。次にエラー対処の仕様をどのようにするかがポイントです。  この場合は最大値で保持するのが良いでしょう。更にその後ディクリメントが有っても最大値を保持したままにするとか。  そのような仕様を抜け目無く考えるのが大変なんですよ。

その他の回答 (4)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.4

> あっているでしょうか? あっているかどうかは、処理系を特定しなければ何ともいえません。 もっと具体的にいうと... 1バイト=8ビットの処理系で、1バイトの整数値について考えた場合、-127の内部表現は次の3種類があります。 10000000 (1の補数表現) 10000001 (2の補数表現) 11111111 (符号ビットと絶対値) さらに、オーバーフローが発生すると例外(C++の例外ではなくハードウェア的なもの)が発生する処理系もあります。 これらを考えると、どうなるかは一概にはいえないことが分かるはずです。

  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.3

こんにちは。 プログラムの動作としては、既に回答が出ている通りです。 「数値の動作」に的を絞ってご質問に答えるとするならば、 >一周して、最低値である-2147483648に加算されてゆくことになるのでしょうか? これはYesです。 ただ、「一周」という表現が少し引っかかるのですが、補数表現に対するご認識は大丈夫でしょうか。 >超えることが予想される場合、対処するべきなのか、 絶対に対処するべきです。 ただ、最大値を超えたら0にする、よりは、最大値を超えそうになったら最大値をキープするようにした方が何となく自然かなという気がします。(もちろん、開発しているソフトの仕様によりますが)

jollno
質問者

お礼

みなさん解答ありがとうございました。 一応対処事態はしていたのですが、その処理しなかった場合、 どのような動作を起こすのかただ気になりましたので 質問させていただきました。 >一周して、補数表現 たとえば1バイトで一番左を符号として考えるなら、 10進数で+127は01111111、-127は10000000などということですよね? なんとなくイメージ的に周回してると捉えていただけです(^^;) 最大値を超えるというのは、01111111+1などを考えると、 10000000となるので、最低値の-127になると考えていたのですが、 あっているでしょうか?

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

符号付き整数のオーバーフローは未定義の動作になります。 処理系不明の状況では、具体的にどう振る舞うかは予測不能だと考えてください。

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.1

オーバーフローは割り込み対象です。 ただマスク出来るので無視したら、+1を続けると 最大値からマイナスの最小値になると思います。 マスクしなければ、ゼロ割のようにプログラムは 落ちます。

関連するQ&A

  • javaScriptの変数をJavaの変数に代入する。

    jspで作ったプログラムがあるこのような場合変数を共有する方法はありますでしょうか? 以下の場合iの(JavaScript)値をjavaの変数iに代入したい場合どうすればいいでしょうか? <%! String s[] ={A,B,C,D,E} %> function chek(){ for(i = 0;i< 5 ;i++){ <%! int i =%> = i;//←この部分です //document.form1.desc.valueにはBの値が入っている if(<%! s[i] %> == document.form1.desc.value){ alert("Bです"); } }

  • カラーを変数に代入したい。

    質問させてください。 jspのプログラムなのですが、HTMLの配色を変数に代入して使いたかったので、こちらに質問させていただきました。 //バックカラー格納変数 String HaCol = "#ffb6c1"; String ShuCol = yellow; 例えばこんな感じで、変数に代入して、 out.println("<td bgcolor=HaCol >" + RESTDAYS + "</td>"); out.println("<td bgcolor=ShuCol >" + STATUS + "</td>"); こんな感じて代入した色を取り出したいのですが、上手くいきません。 どなたか詳しい方、いましたらご指導宜しくお願いします。

    • ベストアンサー
    • HTML
  • 範囲外の数値を代入したらエラーを出して止まるようにしたい

    大きさが3の配列に対して,たとえば, mat[10] = 4 のように代入しようとすると 「OutOfBoundary 云々」というエラーメッセージが出て プログラムが止まりますよね. 同じように,変数に代入できる範囲を制限できないでしょうか? 次のようなメソッドを作りたいたのですが, x に代入できる範囲を (-1, 1) に制限したいと思っています.    public void test(double x) {       if (x >= -1 && x <= 1) {          this.x = x;       } else {          // ここで 「(1, 1)の範囲じゃなきゃダメ」とう          // ことを伝えるメッセージを出して,          // プログラムを止めたい       }    } どうすればよいでしょうか?

    • ベストアンサー
    • Java
  • 関数の引数なしを変数に代入したら入ってきた数値は何?

    デバッグソフトで自分のプログラムを動かしていたときに、 int test_func(char x) { x = x + 1; ------(中略)----------- return x; } int main(void) { int test_val; ------(中略)----------- test_val = test_func; ------(中略)----------- } このようにtest_func(char x)という関数の戻り値を変数test_valに代入するつもりだったのですが、間違って引数部分を書かずにコンパイルしてしまいました。 このときにコンパイルでエラーが出ると思ったのですが、コンパイル完了でデバッガで変数test_valをみてみると何か値が入っていました。 ちょっと気になったのですが、この変数の中に入った値はいったい何なのでしょうか。ご存じの方いらっしゃいましたらご教授お願いいたします。

  • 変数の代入について

    他のファイルを参照し変数に代入しましたが 参照式まで代入されてしまいますが、これを回避したいです。 ='C:\フォルダ名\[ファイル名.csv]シート名'!$A$1 理由としては、参照先を知られたくないためです。 Dim A(9) As Variant A(0) = Path & "!$A$1" 'ここの部分の書き方を教えてください。 .Range("B1").Value = A(0) 変数は入力ミスをした場合に元に戻すために使います。

  • ポインタ変数を変数に渡す方法

    (int * 型)ポインタ変数に代入されたアドレスを、(普通の)int 型変数に代入したいのですが、どのようにするのが正しいのでしょうか。 想定しているケースは、与えられたメモリ番地に対して、アドレスオフセットを加えるなどの操作を施して「補正アドレス」を生成し、メモリアクセスを行う、というような特殊な操作を実現するような場合です。 ※ メモリ番地がポインタ宣言で与えられる、という制約があります。 以下サンプルプログラムを書きました。組み込み系のプログラムを記述していますが、これで正しいでしょうか。 unsigned int *p, *p1; // ポインタ変数宣言 unsigned int value; p= (unsigned int *)0x00001F00; // メモリの0x1F00番地 value = p; // <-- ここが心配 value |= 0xCC << 16; // 与えられたアドレスから value &= 0x4 << 12; // 「補正アドレス」生成 p1 = (unsigned int *)value; *p1 = 0xA5A5_A5A5; // 「補正アドレス」にA5A5... をライト C言語初心者で、いろいろなサイトを見てみたのですが、説明されているページが見つからず質問させていただきました。どうぞよろしくお願いします。

  • 複素変数に値が正しく代入されない

    複素変数を使ったプログラムを作るために、 まず複素変数を作成して値を表示するだけのプログラムを作ったのですが、 虚数部分に代入されるはずの値が実数部分に表示され、 虚数部分には0が表示されてしまいます。 書いたプログラムは #include<stdio.h> #include<complex.h> int main(void){ complex<double> a=(1.2,2.3); printf("%g %gi\n",real(a),imag(a)); } 結果は 2.3 0i でした。 どこで書き方を間違えているのでしょうか。 cファイルだとcomplex.hをインクルードしようとすると stdcomp.hでエラーが出るのでcppファイルにしています。 コンパイラはBorland C++ Compiler 5.5を使っています。

  • マクロに変数を代入

    題名のとおりなのですが 例えば Range("X").Select Selection.Copy Range("Y").Select ActiveSheet.Paste のXYに変数の行列 X Y a1 a2 b1 b2 c1 c3 等を代入してマクロ繰り返し試行させることは可能なのでしょうか?

  • charで宣言した変数をstringへの代入で

    wchar_t cOrg[128]と宣言している変数にstringで宣言しているstrを cOrg[i] = str[i]; このように代入することはできたのですが、 char cAns[ 128 ]; このように宣言した変数の値をstrの41番目と42番目に 次のように入れようとするとエラーが出ます。 str[41]=cAns[1]; str[42]=cAns[2]; (エラー内容) \Form1.h(428): error C2664: 'System::String::String(wchar_t,int)' : 1 番目の引数を 'wchar_t [128]' から 'wchar_t' に変換できません。(新しい機能 ; ヘルプを参照) このような代入はできないのでしょうか? プログラムの詳細は下のようなものです。 wchar_t cOrg[128],*p; String^ str; String^ str2; int i; int iVal1,iVal2,iTotal = 0,iHosu; char cAns[ 128 ]; str = this->textBox1->Text; for(i=0;i<41;i++) { cOrg[i] = str[i]; } -------(中略)------------------------------------------ iHosu = ~iTotal; // 1の補数 iHosu++; // +1 iHosu = iHosu & 0x00FF; sprintf( cAns, "%s%02X%c", cOrg, iHosu, 0x22 ); str[41]=cAns[1]; str[42]=cAns[2];

  • C言語の代入についての質問です

    C言語の代入についての質問です 下のプログラムを見て下さい #include<stdio.h> int x[2]; x[0] = x[1] = 1; int main(void) { for(int i = 0 ; i < 2 ; i++) printf("%d",x[i]); putchar('\n'); return 0 ; } このプログラムをコンパイラすると3行目の代入にエラーが出されます (当たり前ですがmainの中に3行目の代入文を入れると上手くいきます) まぁそれがなぜかというのが知りたいのですが、 それはC言語をつくった人が決めたことなのでしょうか? ちなみに異なる実行環境でやってみたらどれも駄目だったので これが上手くいくことはない?のだと思います そういうもんなのだったら、そういうものだと理解しますが もし理由を知っている方がいらっしゃったら教えて下さい

専門家に質問してみよう