• ベストアンサー

(プログラムがあるため長文です)次の2つの違いは?

C言語(VisualStudio.net2003)で組み合わせに関するプログラムを作成したのですが、(1)の式で、プログラムを実行させると、違う結果が出てしまい、(2)の式で実行させると、正しい結果が出ます。 (1)(コピーして、確認(実行)してみてください) #include <stdio.h> int main ( void ) { int n,r,k; int a=1; printf("n=?");scanf("%d",&n); printf("r=?");scanf("%d",&r); for ( k=1 ; k<=r ; k++){ a *= (n-k+1)/k; printf("a%d=%d\n",k,a); } return 0; } (2)a *= (n-k+1)/k; の部分を a = a*(n-k+1)/k; に変更する。 a *= (n-k+1)/k;という式が、a = a*(n-k+1)/k;ということを意味しているので、どちらでも正しい結果がでる気がするのですが、なぜ(1)では正しく結果が表示されないのでしょうか?教えてください。 また、(1)のような *= をつかってプログラムを組みたいとき、a *= (n-k+1)/k; をどのように変更すればよいのでしょうか?

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

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

(1)のとき、まず (n-k+1)/k を計算(※)してから、 その結果を a に掛けています。つまり、 a = a * ((n-k+1)/k); と同じことをしています。このとき、(※)の整数どうしの割り算で、 ちょうど割り切れる場合もありますが、 小数点以下の端数が出て、それを切り捨てる場合もあります。 後者の場合、a の最終的な値は正しくなくなってしまいます。 *= 演算子を使ってこれを防ぐには、例えば a *= n - k + 1; a /= k; のようにする必要がありそうです。ただ、この場合、n と k の値によっては 最初の掛け算のところでオーバーフローするおそれがあります。 掛け算の結果が int型で扱える範囲に収まっている限りは大丈夫です。

hyper1234
質問者

お礼

解答ありがとうございます。 a *= n - k + 1; a /= k; としたら正しい結果になりました。 また、型キャストで、a *= double(n-k+1)/double(k);としても、きちんとした結果が得られました。 ということは、コンピュータが行った計算結果は正しいが、型が違うため、その値を表示できなかったということですね・・・ 今回の質問をして、同じ結果を表すものでもいろいろなプログラムの書き方があることを知りました。 もし、また分からないことがあったときにはよろしくお願いします。

その他の回答 (1)

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

変数 a が int 型のため、(n-k+1)/k が整数にまるめられてから a にかけ算されるのと、a*(n-k+1)/k が整数にまるめられた結果が異なるのでしょう。

hyper1234
質問者

お礼

早速の解答ありがとうございます。 型キャストで、a *= double(n-k+1)/double(k);としたところ、きちんとした結果が得られました。 ということは、コンピュータが行った計算結果は正しいが、型が違うため、その値を表示できなかったということですね・・・ もし、また分からないことがあったときにはよろしくお願いします。

関連するQ&A

  • 昇順に並べ替えるプログラム(続き)

    (C言語)実行例のような3つの整数を読み込み昇順に並べ替えるプログラムは途中までわかったのですがあとはどう修正・追加をすればいいのでしょうか? 実行例 1:45 2:43 3:38 昇順に並べ替えました。 1:38 2:43 3:45 途中までのプログラム #include<stdio.h> int main(void) { int n1,n2,n3; printf("1:"); scanf("%d",&n1); printf("2:"); scanf("%d",&n2); printf("3:"); scanf("%d",&n3); printf("昇順に並べ替えました。\n"); return 0; }

  • プログラムがうまくいきません。教えてください。

    プログラムがうまくいきません。教えてください。 #include <stdio.h> int main(void){ int a, b, c, d, f; printf("国語="); scanf("%d", &a); printf("算数="); scanf("%d", &b); printf("理科="); scanf("%d", &c); printf("社会="); scanf("%d", &d); f = ((a>90)?1:0)+((b>90)?1:0)+((c>90)?1:0)+((d>90)?1:0); printf("\n合計[%d],平均[%.2f]\n",(a+b+c+d),((double)(a+b+c+d)/4.0)); printf("国語[%d],[%.3f%%],[%d]\n",a,((double)a/1.5),((a>90)?1:0)); printf("算数[%d],[%.3f%%],[%d]\n",b,((double)b/1.5),((b>90)?1:0)); printf("理科[%d],[%.3f%%],[%d]\n",c,((double)c/1.5),((c>90)?1:0)); printf("社会[%d],[%.3f%%],[%d]\n",d,((double)d/1.5),((d>90)?1:0)); printf("総合判定[%d],\n", ((f>=3)?1:0)); return (0); } と入力したのですが、実行結果の国語から社会までの[]部分を上下揃えたいのですが揃いません。このプログラムにどのようなことを追加すれば揃えることができますか?教えてください!

  • このプログラム見てください

    これで動いたと書いてあるのに動きません。 どこを直せば良いのか教えてください。 #include <stdio.h> int combination(int n,int r){ if ( r==0 ){ return 1; }else if( r==n ){ return 1; }else{ return (combination(n-1,r-1)+combination(n-1,r)); } } int main(){ int num_n=0; int num_r=0; int answer=0; printf("組み合わせの計算をします。数値を入力してください。N=?。\n"); printf("[n]:"); scanf("%d",&num_n); rewind(stdin); printf("[r]:"); scanf("%d",&num_r); rewind(stdin); answer=combination(num_n,num_r); printf("%dC%d=%d\n" , num_n, num_r, answer); return 0; }

  • プログラムに詳しい方教えてください!

    #include<stdio.h> void fxl(int x,int y); int main(void) { int a,b,m,n; printf("整数aの値を入力\n"); scanf("%d",&b); printf("整数bの値を入力\n"); scanf("%d",&b); m=a; n=b; fxl(m,n); printf("a=%dとb=%dを加算した値は%d\n",ab,m); printf("a=%dからb=%dを減算した値は%d\n",ab,n); return 0; } void fxl(int x,int y) { int j,k; j=x; k=y; x=j+k; y=j-k; } このプログラムを作ってみたのはいいのですが、参照渡しを使って正常に足し算、引き算をするにはどうすればよいのでしょうか。

  • 次のプログラムは、n個の中からr個とる組み合わせが何通りあるか求め出力

    次のプログラムは、n個の中からr個とる組み合わせが何通りあるか求め出力するものである。 ただしこの組み合わせは次のようにけいさんするものである nCr=n!/r!×(n-r)! ○の中にあてはまる数値や文字を教えてください C言語です #include<stdio.h> void main(void) { int a,b,n,r,cnt; int kumiawase; a=○; b=1; printf("n=10"); scanf("%d",&n); printf("r=3"); scanf("%d",&r); for(cnt=n;cnt>1;cnt--){ a=○; } for(cnt=r;cnt>1;cnt--){ b=b*cnt; } for(cnt=○;cnt>1;cnt--){ b=b*cnt; } kumiawase=○/○ printf("%d個から%d個とる組み合わせ=%d\n",n,r,kumiawase); }

  • n^kのwhile文のプログラムについて

    下のプログラムを実行すると無限に計算されるのはなぜですかどこがおかしいか教えてください /* while1.c---for bun* n no jou*/ main() { int n,k,m,i; printf("Input n\n"); scanf("%D",&n"); printf("Input k\n"); scanf("%d",&k"); m=1; while (i<=5) { m=m*n; printf("%d no %d jou =%D\n",n,i,m); i++; } } あとこれをdo while文にするにはどうすればいいんですか

  • プログラムの練習問題をやっていたのですが、練習問題の答えのような実行結

    プログラムの練習問題をやっていたのですが、練習問題の答えのような実行結果にならないので教えていただけませんか? 下記に記したプログラムを実行すると x=9 y=-9 [ 9]*[-9]=[ -81],[ 9]*[-8]=[ -72],[ 9]*[-7]=[ -63],・・・・ ・・・・ [10]*[-9]=[ -90],[10]*[-8]=[-80],・・・・ ・・・・ のようになるのですが、 x=9 y=-9 [ 9]*[-9]=[ -81],[10]*[-9]=[-90],・・・ [ 9]*[-8]=[ -72],[10]*[-8]=[-80],・・・ [ 9]*[-7]=[ -63],・・・ ・・・・ のようにするためにはどうすればいいですか? #include <stdio.h> int main(void) { int x,y,m,n; printf("x="); scanf("%d",&x); printf("y="); scanf("%d",&y); for(m=x;m<=x+3;m++) { printf("\n"); for(n=y;n<=y+14;n++) { printf("[%2d]*[%2d]=[%4d],",m,n,m*n); } printf("\n"); } return(0); }

  • プログラムの中から別なプログラムを実行する

    現在、プログラムAを利用しています。プログラムAを何度も実行するようループ処理を加えたいのですが、インクルードファイルが行方不明になり、プログラムAのソースに手を加えてコンパイルすくことが出来なくなりました。 そこで、プログラムBを作り、その中からAを実行することでループさせたいのですが可能なのでしょうか?もし可能ならどのようにすればいいのか教えてください。よろしくお願いします。 プログラムAは次のようになっています。 #include <stdio.h> int avn; int nos; float fac; char fh[20]; void main(void){ printf(" input average number \n "); printf("0=>100,1=>200,2=>500,3=>1000 shots \n"); printf(" 10, 20, 50, 100 sec \n"); printf(" number = "); scanf("%d",&avn); printf(" number of records = "); scanf("%d",&nos); printf(" number / factor = "); scanf("%f",&fac); printf(" file head = "); scanf("%s",fh); printf("%d,%d,%f,%sが設定されました",avn,nos,fac,fh); } printf文の所には本来別の処理が入ります。

  • 学校の課題で2次方程式のプログラムを作ってみたのですが、足りない部分ががあるらしいのでお教えてください

    キーボードからある整数の値を入力して、2次方程式を解くというプログラムを作ったのですが、解の方程式のところでどこかが足りないらしいのですが教えてください。 #include<math.h> #include<stdio.h> int quadraticEquation(double a, double b, double c){ int x,y,l,k,j; double z; x=b*b; y=4*a*c; z=x-y; if(z>=0){ l=sqrt((double)z); } else printf("ERROR!!\n"); k=(-b)+l; j=k/2*a; return j; } int main(void){ int n1,n2,n3; printf("input three integer!\n"); printf("intger1:"); scanf("%d",&n1); printf("intger2:"); scanf("%d",&n2); printf("intger3:"); scanf("%d",&n3); printf("kotaeha %d %d desu\n",quadraticEquation(n1, n2, n3),quadraticEquation(n1, n2, n3)); return 0; } が自分が作ったプログラムです。 後、解が2つある場合の出力方法がこれであっているかどうかも教えてください。 よろしくお願いします。

  • C言語プログラムについての質問です。下のプログラムがなぜ降順で出力され

    C言語プログラムについての質問です。下のプログラムがなぜ降順で出力されるのか分かりません。何回も確認したのですが、不等号の向きが昇順になっているのに、どうして降順になるのかが理解できません。 ご教授お願いします。   #include <stdio.h>   #define MAX 10000   int main (int argc, const char * argv[]) { int N,data[MAX],d[MAX],j,k,w,x,a; x=0; a=1; do{printf("学生番号を入力してください\n");    scanf("%d",&N);   if(N!=0){printf("得点を入力してください\n"); scanf("%d",&data[N]);}x++;} while(N!=0);   for(j=0; j<x;j++){ d[j]=data[j];} for(j=0; j<x;j++)      {for(k=0;k<x-j-1;k++){   if(d[k]>d[k+1]){ w=d[k]; d[k]=d[k+1]; d[k+1]=w;}}} printf("昇順での整列結果\n"); for(j=x-1;j>0;j--){ printf("%d位 %d点\n",a,d[j]);a++;} return 0; }

専門家に質問してみよう