- ベストアンサー
オーバーフローについて。
/* 符号無しの算術演算がオーバーフローを起こさないことを確認 */ という、ソースについて教えてください。 #include <stdio.h> #include <limits.h> int mani(void) { unsigned x = UINT_MAX - 1; printf("unsigned型の最大値:%u\n", UINT_MAX); printf("x = %n\n", x); printf("x + 3 = %u\n", x + 3); printf("x * 2 = %u\n", x * 2); return(0); } まず、 (1)unsigned x = UINT_MAX - 1; についてですが、何故1を引く必要があるのでしょうか? 別に1を引かなくてもいい気がするのですが・・・ (2)printf("x + 3 = %u\n", x + 3); printf("x * 2 = %u\n", x * 2); についてですが、x = 65534 に + 3 にしたり、* 2 にすることで、何が言いたいのかがわからないので、教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
その他の回答 (3)
- kuma_rider
- ベストアンサー率40% (40/100)
- zwi
- ベストアンサー率56% (730/1282)
- shirayukix
- ベストアンサー率43% (90/207)
関連するQ&A
- 困っています
どうしても、--unsigned型のビット内容表示--の所が意味が分かりません。分かりやすく教えてください。宜しくお願いします。 /* 0~UINT_MAXを2進・8進・16進で表示 */ #include <stdio.h> #include <limits.h> /*--- 整数xのセットされたビット数を返す ---*/ int count_bits(unsigned x) { int count =0; while (x) { if (x & 1u) count++; x>>=1; } return (count); } /*---- unsigned型のビット数を返す ----*/ int int_bits(void) { return (count_bits(~0U)); } /*---- unsigned型のビットを内容を表示 ---*/ void print_bits(unsigned x) { int i; for (i=int_bits() -1; i>=0; i--) putchar(((x>>i) & 1U) ? '1' : '0'); } int main(void) { unsigned i; for (i=0; i<UINT_MAX; i++) { print_bits(i); printf(" %6o %5u %4X\n", i, i, i); } return(0); }
- ベストアンサー
- C・C++・C#
- 加減剰余のオーバーフローについて
今C言語で加減剰余のプログラムを作っていて、 オーバーフローのチェックだけが上手くいきません。 limits.hをインクルードして、オーバーフローのチェック を行いたいのですがどうすればよいのでしょうか? 扱いたい範囲はint型の-2147483648~2147483647です。 ちなみに開発環境はvc++2005です。 一応ソースを載せておきますので、よろしくお願いします。 #pragma warning ( disable : 4996 ) #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <limits.h> int main ( int argc, char *argv[] ) { int start; // 最初に入力する値(引数1) int end; // 最後に入力する値(引数3) int kekka; // 計算結果を格納 int amari; // 除算の余りを格納 int max = INT_MAX; // 表すことが出来る最大値 int min = INT_MIN; // 表すことが出来る最小値 char enzansi; // 入力する演算子 (引数2) char str1[512]; // 格納用の配列を宣言(start用) char str2[512]; // 格納用の配列を宣言(end用) /* 引数の個数チェック */ if ( argc != 4 ) { printf ( "usage : %s start enzansi end\n", argv[0] ); exit ( 0 ); } /* 引数を取得して整数型に変換 */ start = atoi ( argv[1] ); end = atoi ( argv[3] ); /* 引数の取得 */ enzansi = ( argv[2][0] ); sprintf ( str1, "%d", start ); // str1に値を格納 sprintf ( str2, "%d", end ); // str2に値を格納 /* str1とargv[1]による文字列の比較 */ if ( strcmp ( str1, argv[1] ) ) { printf ( "error : 整数を入力して下さい。\n" ); exit ( 0 ); /* str2とargv[3]による文字列の比較 */ } else if ( strcmp ( str2, argv[3] ) ) { printf ( "error : 整数を入力して下さい。\n" ); exit ( 0 ); /* argv[2]が2文字以上の場合 */ } else if ( strlen ( argv[2] ) >= 2 ) { printf ( "error : 演算子を正しく入力して下さい。\n" ); exit ( 0 ); } /* 入力された演算子の条件ごとに計算 */ if ( enzansi == '+' ) { kekka = start + end; } else if ( enzansi == '-' ) { kekka = start - end; } else if ( enzansi == '*' ) { kekka = start * end; } else if ( enzansi == '/' ) { /* startの値を0で除算する場合 */ if ( end == 0 ) { printf ( "error : 0による除算は禁止です。\n" ); exit ( 0 ); } kekka = start % end; // 剰余を求める /* 割り算の結果として余りが出なかった場合 */ if ( kekka == 0 ) { kekka = start / end; printf ( "%d %c %d = %d", start, enzansi, end, kekka ); exit ( 0 ); /* 割り算の結果として余りが出た場合 */ } else if ( kekka != 0 ) { kekka = start / end; amari = start % end; printf ( "%d %c %d = %d余り%d", start, enzansi, end, kekka, amari ); exit ( 0 ); } /* 入力された演算子が異なる場合 */ } else { printf ( "error : '+' '-' '*' '/'のいずれかの演算子を入力して下さい。\n" ); exit ( 0 ); } /* 数値1 演算子 数値2 = 演算結果の形式で出力する */ printf ( "%d %c %d = %d", start, enzansi, end, kekka ); exit ( 0 ); } もし変な部分がありましたら指摘お願いします。 一応四則演算は問題なくできます。
- ベストアンサー
- C・C++・C#
- オーバーフローを繰り返したときの挙動
#include <stdio.h> int function(int x){ if(x==1) return 1; else return x*function(x-1); } int main(){ int x; x = function(50); printf("%d\n",x); } 50!を計算するプログラムを作成し、VC++とgccでそれぞれコンパイルして実行したところ結果は0と表示されました。 途中でオーバーフローしているのは分かるのですが、数回オーバーフローを繰り返した後にfunctionの戻り値が-2^31に収束し、最終的に0になります。 何故このような挙動をするのでしょうか?
- ベストアンサー
- C・C++・C#
- intとlongは同じ?
#include <stdio.h> #include <limits.h> int main() { printf("%d\n%d", INT_MAX, LONG_MAX); return 0; } 出力 214783647 214783647 Win7 64bit (VC++2010) CentOS 32bit (gcc) どちらの環境でも同じ出力結果となりました。 intとlongなぜ同じになってしまったのでしょうか。
- ベストアンサー
- C・C++・C#
- ALUのオーバーフローフラグの生成条件の証明などの問題
ALUのオーバーフローフラグの生成条件の証明などの問題 A,Bを2の補数による符号付きnビット2進数の整数入力とする。nビットALUの演算結果により生成される条件判定フラグ、すなわちN(Negative)、 V(oVerflow)フラグについて書の問に答えよ。ただし、ALUの演算結果は(F[n-1]・・・F[0])とし、ALUを構成する加算回路の桁上げ出力に おいて、最上位の桁上げ出力はC[n]、その1ビット下位の桁上げ出力をC[n-1]とする。 (1)オーバーフローフラグV(oVerflow)を生成する条件が"C[n]xorC[n-1]=1"となる事を証明せよ。 (2)上記ALUを用いた算術比較演算において、A<Bの判定条件がオーバーフローの有無に関係なく、"N xor V=1"となる事を証明せよ。 ------------------------------------------------------------ このような問題があるんですが、解答は分かりません。 証明せよとは一体どのように記述すればいいんでしょうか? あと、(2)は何故"N xor V=1"と表せるんでしょうか? 一応、自分で考えたのはこんな感じです。 (1) 加算時のオーバーフローの条件は、 符号がA,B共に負、つまりC[n]が1でかつ、nビット目が1にならずに、正の値になってしまう数であるC[n-1]=0の場合と、 符号がA,B共に正、つまりC[n]が0でかつ、nビット目が1にならずに、負の値になってしまう数であるC[n-1]=1の場合である。 よって、オーバーフローフラグが生成される条件をC[n]xorC[n-1]=1と表すことができる。 (2) 演算結果が負でかつ、オーバーフローが発生していなければA<Bだから?分かりません。
- ベストアンサー
- その他([技術者向] コンピューター)
- C言語の課題が分からなくて困っています。
http://www.picamatic.com/view/5868047_かかか/ URLの画像のような数当てゲームのプログラムを作成しているのですが、(1)~(5)の部分が分からなくて困っています。 面倒だとは思いますが、教えていただけないでしょうか。 #include<stdio.h> #include<stdlib.h> #include<time.h> int mani(void){ int i,x,y; srand((unsigned int)time(NULL)); (1) //1~1000の数をランダムに作成 y=0; //入力回数yを0にセットする for(;;){ //break文があるまで以下の処理を繰り返す printf("1以上1000以下の整数を入力してください。\n"); (2) //答えの入力 y=y+1; //入力回数yを1を増やす (3) //あたりの場合 printf("%d回目で当たりました。\n",y); (4) } else{ //外れの場合 (5) printf("違います。もっと大きな数です。\n"); else printf("違います。もっと小さな数です。\n"); } } return 0; }
- ベストアンサー
- C・C++・C#
- C言語による浮動小数点表示
#include<stdio.h> #include<math.h> main() { float a=1.5*pow(2,-15); unsigned char *e; e=(unsigned char *)&a; printf("a=%02x,%02x,%02x,%02x\n",*(e+3),*(e+2),*(e+1),*(e+0)); } というプログラムで a=38,40,00,00 という結果がでたのですが これは何を表しているのでしょうか? よろしくおねがいします
- ベストアンサー
- C・C++・C#
- Visial C++おけるπの使い方
自宅でCプログラミングの練習をするためVisial C++ 2008を使って プログラムをしています。y<sin(πx)となった時の 割合などを計算するプログラムで 「M_PIが定義されていない識別子です」 とでてきます。所持している本を参考にしてもM_PI=πとして用いる と書いてあり、math.hもインクルードしてるので原因が分からなくて 困ってます。Visial c++ではπの使い方には何か別の使い方がある のでしょうか?よろしくお願いします。 *↓が実際に作ったプログラムです。 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> int main(void){ int i,n,count=0; double x,y,r,error; srand((unsigned)time(NULL)); /*乱数の初期化*/ printf("How many trials?"); scanf("&d",&n); for(i=0;i<n;i++){ x=rand()/(RAND_MAX+1.0); y=rand()/(RAND_MAX+1.0); if(y<sin(M_PI*x)){ count++; } } r=(double)count/n; /*キャスト演算子を使用*/ error=2/M_PI-r; printf("Result is %f (Error: %f)\n",r,error); return 0; }
- ベストアンサー
- C・C++・C#
- 初心者の作ったプログラムの問題点を指摘ください。
下のように、0から9までの乱数の発生回数の標準偏差を求めるプログラムを組んでみたのですが、最後のシグマの演算が無視されてしまい、0.000000と出力されてしまいます。どこがいけないのでしょうか? #include<stdio.h> #include<time.h> #include<stdlib.h> #include<math.h> int main (void){ int N,i,j,r,a[10]={0,0,0,0,0,0,0,0,0,0}; double S=0; printf("How many trials?;"); scanf("%d",&N); srand((unsigned)time(NULL)); /*初期化*/ for(i=0;i<N;i=i+1) { r=(int)(rand()/(RAND_MAX +1.0)*10); /*乱数N個取得*/ a[r]=a[r]+1; } for(r=0;r<10;r=r+1){ printf("a[%d]=%d.\n",r,a[r]); S=1/10*(S+sqrt((a[r]-N/10)*(a[r]-N/10))); /*演算(無視されてしまう・・・)*/ } printf("Sigma=%f",&S); return 0; }
- ベストアンサー
- C・C++・C#
- 何故オーバーフロー??
http://oshiete1.goo.ne.jp/qa4423673.html さらに続きになります。 #include<stdio.h> #include<string.h> #define NAME 256 // 暫定的に最大値を決めてます int Convert(const char* pInFileName, const char* pOutFileName); int ReConvert(const char* pInFileName, const char* pOutFileName); int main(){ int a,ret=-1; char InFileName[NAME]; // 入力ファイル名 char OutFileName[NAME]; // 出力ファイル名 FILE *pInFileName; // 入力ファイルポインタ FILE *pOutFileName; // 出力ファイルポインタ printf("1:コンバート 2:リコンバート\n"); scanf("%d",&a); /***** 入力ファイル名入力 *****/ printf("\n@@@@@入力ファイル名入力\n"); scanf("%s",&InFileName); // 入力ファイルオープン if((pInFileName=fopen(InFileName,"rb"))==NULL){ printf("ファイルがありません\n"); return -1; } /***** 出力ファイル名入力 *****/ printf("\n@@@@@暗号化後ファイル名入力\n"); scanf("%s",&OutFileName); // 出力ファイルオープン if((pOutFileName=fopen(OutFileName,"r"))!=NULL){ // read出来るのなら既にファイルあるという事なのでエラーにする printf("同名のファイルが既にあります\n"); return -1; } pOutFileName=fopen(OutFileName,"wb"); // 1:コンバート // 2:リコンバート // 1,2以外:終了 if(a==1){ ret=Convert((const char*)pInFileName,(const char*)pOutFileName); } else if(a==2){ ret=ReConvert((const char*)pInFileName,(const char*)pOutFileName); } if(ret==0){ printf("正常終了\n"); } else{ printf("異常終了\n"); return -1; } printf("数字+エンターで終了します\n"); scanf("%d",&a); fclose(pOutFileName); fclose(pInFileName); return 0; } /*****コンバート*****/ int Convert(const char* pInFileName, const char* pOutFileName) { unsigned char moji; while(1) { if(fread( &moji, 1, 1, (FILE*)pInFileName )>0){ fprintf((FILE*)pOutFileName,"%02x",moji); } else break; } return 0; } /*****リコンバート*****/ int ReConvert(const char* pInFileName, const char* pOutFileName) { char moji16[3]; // 16進表記 char moji10[4];★★★★★★★★★★ long i,j; while(1) { if(fread( moji16, 1, 2, (FILE*)pInFileName )>0){ for(i=0,j=0;i<2;i+=2,j++){ sscanf(&moji16[i], "%2x", moji10); } fprintf((FILE*)pOutFileName,"%c",moji10); } else break; } return 0; } 上記の char moji10[4];★★★★★★★★★★ の部分ですが、これを配列を用いずに、moji10とした場合(応じてsscanfでは&moji10になる)や moji10[2]、moji10[3]とした場合でもオーバーフローが検出されました。 sscanfの行になった時に、moji10[0]には文字が入りますが、 moji10[1]~moji10[3]まで、NULL文字'\0'が入っていました。 何故moji10[4]にしないとオーバーフローが消えないのでしょうか? 尚、Visual C++ 2008です。
- ベストアンサー
- C・C++・C#
お礼
回答ありがとうございます。 凄く理解しました。 また宜しくお願いします。