• ベストアンサー

簡単な割り算プログラムとprintfについて。

趣味のプログラミングで二つの整数x, yの割り算結果x/yを分数(約分も行う)、または少数で表示するプログラムを作成中です。 分子が1になる場合は分数、それ以外は少数で表示しなくてはなりません。 しかし、 二つの整数が1, 111の場合など、割り算の結果が無限少数になってしまう場合は、 1/111と表示しなくてはいけません。 例) x = 100, y = 200, kekka = 1/2 x = 4, y = 5, kekka = 0.8 x = 1, y = 111, kekka = 1/111 わたしは初めに、x ,yを比較してxのほうが大きい、または最大公約数がxと等しい場合はx/yを少数で表示し、 それ以外なら最大公約数で両方を割って分数で表示、という風に考えていましたが、 条件の無限小数の判定の方法がどうしても分かりません。 また、もし結果が0.0003などの場合、printf("%.4f", kekka); と書けば、0.0003とキレイに表示されますが、 printf("%f", kekka);のままでは、0.000300とゼロが余計に表示されてしまいます。 この桁数指定を引数などで与える方法が分かりません。 もしお詳しいかたいらっしゃいましたら、ご教授ください。 よろしいお願いします。

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

  • ベストアンサー
回答No.2

>条件の無限小数の判定の方法がどうしても分かりません。 桁に制限が付きますが次の方法が一番簡単に判定できると思います。 if( x * 1000000 % y == 0 ) >この桁数指定を引数などで与える方法が分かりません。 ご希望の処理方法とは違いますが、 %fではなく、%gにすると桁数指定をするまでもなく0が消えます。 また、引数を指定することにこだわるなら、 char c[10] = "%.5f"; c[2] = '3'; printf( c, 0.005f ); 実行結果 0.005 のような書き方もあります。

sakikomait
質問者

お礼

ご回答ありがとうございました。 とても勉強になりました。

その他の回答 (1)

  • Werner
  • ベストアンサー率53% (395/735)
回答No.1

> 条件の無限小数の判定の方法がどうしても分かりません。 約分した後の分母を素因数分解して、 2か5以外の因数が有れば無限小数。 (実際に素因数分解しなくても、 2または5で割る操作を余りが出ない間繰り返して商が1になるかという判定で良さそう。) > また、もし結果が0.0003などの場合、printf("%.4f", kekka); と書けば、0.0003とキレイに表示されますが、 > printf("%f", kekka);のままでは、0.000300とゼロが余計に表示されてしまいます。 > この桁数指定を引数などで与える方法が分かりません。 たしかアスタリスクを使って、  printf("%.*f", kekka, prec); とすれば引数で精度指定ができたと思う。 もしくは面倒だけど、printfの%f指定子に頼らずに、 分母が10の倍数になるように分母・分子に同じ数をかけた後、 分子を文字列に変換し適切な位置に小数点を入れるという手順でもできなくはないか。

sakikomait
質問者

お礼

ご回答ありがとうございました。 とても勉強になりました。

関連するQ&A

  • 既約分数の表示プログラム

    (1)キーボードから,分子,分母に相当する整数2つを入力し,その既約分数を表示せよ。 (2)分母が1の時には,分子のみを表示する。 (3)分子と分母の符号が異なるときにのみ,-符号を表示する。 (4)分母がゼロの入力エラーに対しては、再入力するように促す。 (5)分子と分母の最大公約数も求めて表示する。 (6)また、正しく計算できる最大規約分数を示せ。 #include <stdio.h> int main(void) { int a,b,i=1,x,y,z; printf("分子=");/*分子の入力*/ scanf("%d",&a); printf("分母=");/*分母の入力*/ scanf("%d",&b); if(b==0) { printf("分母が0です。入力が誤っています。\n"); return 0; } if(b==1) { printf("既約分数は %d\n",a); return 0; } while((i<=a)&&(i<=b)) { if((a%i==0)&&(b%i==0)) { x=i;i=i+1; /*xを上書きしていく*/ } else { i=i+1; } } printf("分子と分母の最大公約数=%d より\n",x); y=a/x; z=b/x; printf("既約分数は %d/%d\n",y,z); return 0; } 大学の課題で出されたものです。(1)(2)(4)(5)はできたのですが、(3)と(6)の部分のやり方がいまいちよくわからなかったので質問しました。 どなたかご教授お願いできないでしょうか・・・。

  • printf、最大値の出し方

    3つの整数を入力し、どれが最大値かを判別するプログラムを作りたいです。 #include<stdio.h> main() { int i, x, max; max = 0; i = 1; while(i <= 3) { printf("整数:"); scanf("%d",&x); if (x > max) { max = x; } i++; } printf("最も大きい整数は%d\n", max); } とすると 整数:と3回表示されますが、これを一つ目の整数:、二つ目の整数:3つ目の整数:と表示されるようなプログラムにするにはどうしたらよいでしょうか。

  • 小学校5年の割り算

     小学5年の算数の宿題をしてて ふと思いました。  割り算の問題ですが、  5Kmの0.4倍は何Kmでしょうか?    私は下記の式で計算しましたが、ドリルの一番上に 「少数の割り算」と書かれてます。  この場合は、やはり割り算で計算しろという事でしょうか?  5 x 0.4 = 2   答え 2km  分数にして式を書いても、  1分の5x5分の2=5分の10=2 になります。  割り算にて答えを出す場合の式を教えてください。

  • rubyで整数どうしの割り算 切捨てしたくない

    rubyで整数同士の割り算をすると、割り切れないときに小数はきりすてされるようですが、切捨てしたくないときはどうしたらよいのでしょうか 例 a = 1 b = 100 printf("%5.5f / %5.5f = %5.5f\n",a,b,a/ b) 結果 1.00000 / 100.00000 = 0.00000 となってしまいます 1.00000 / 100.00000 = 0.01000 となってほしいです 割り算のまえにto_fする方法を試しましたが結果は同じでした a = 1 b = 100 a.to_f b.to_f printf("%5.5f / %5.5f = %5.5f\n",a,b,a/ b) よろしくお願いします!

    • ベストアンサー
    • Ruby
  • このプログラム見てほしいです!!

    #include <stdio.h> int gcd2(int a, int b) { if (!b) return a; return gcd2(b, a%b); } int main() { int a, b, c; printf("2つの任意の整数を入力せよ:"); scanf("%d %d",&a,&b); c=gcd2(a,b); printf("最小公倍数は%d\n",a*b/c); printf("最大公約数は%d\n",c); return 0; } で、最小公約数を出すことはできたのですが、全ての公約数を表示させたいんです!!どうやったらいいのでしょうか??プログラミングまだ初心者なので、ちょっと行き詰ってしまいました。。。 お時間があればでいいのですが、もう一つわからないプログラムがあります。 自然数nを入力し、x^2+y^2=z^2 (x<y)を満たすようなn以下の自然数の組(x,y,z)がいくつあるのかを出力するプログラムなのですが、全くわからず行き詰っています。。どなたかお時間があれば教えて頂きたいです。 色々と申し訳ありません。お願いします(__)

  • 分数の足し算をさせるプログラムが分かりません。どなたか分かりませんか?

    分数の足し算をさせるプログラムが分かりません。 C言語の問題で分数の足し算までは一応できるんですが、答えがでたときに整数で出すやり方と約分して表す方法が分かりません。 どなたか知恵を貸してくれませんか? ユーザから4つの整数を入力し、はじめに入力された2個の整数と後に入力された2個の整数を分数と考え、その分数の和を表示するプログラムを作成せよ。 例えば、「3」「4」「5」「6」と入力されたときは、3/4 + 5/6を計算する。 そのプログラム内では分数の和を計算する関数を作成する。 さらに、 約分を行う関数を 再帰呼び出しを利用して作成する。 void yakubun(int *a1, int *a2) 例えば、以下の場合1/2と表示される。 int i=10,j=20; yakubun(&i,&j); printf(“%d / %d”, i, j); ちなみにここまでできました↓ #include<stdio.h> void bunsu_tasizan(int a1,int a2,int b1,int b2, int *c1,int *c2 ) { *c1=(a1*b2)+(b1*a2); *c2=(a2*b2); } int main() { int x1,x2,y1,y2,z1,z2; printf("整数を入力してください"); scanf("%d",&x1); scanf("%d",&x2); scanf("%d",&y1); scanf("%d",&y2); if(x2==0||y2==0||x2==0&&y2==0) printf("0以外を入力してください"); else{ bunsu_tasizan(x1,x2,y1,y2,&z1,&z2); printf("%d/%d",z1,z2);} return (0); }

  • 2つ分数の四則演算を行うプログラム

    <要求事項> 分数は、 例)1|3 のように表す。 1.分母がゼロの時はエラーとする。 2.除算において、除数がゼロの入力エラーに対しては、再入力するように促す。 3.以下範囲の整数(分子、分母にかかわらず)に対して、正しく計算できるようにする。   -2147483648 ~ 2147483647 4.計算結果については,分母が1の時には分子のみ表示。分数がの時には0のみを表示。最終計算結果は既約分数にする。分数が負数の場合、-を分数の前に表示。 #include <stdio.h> #include <math.h> int main(void) { int b,d; /* 分母*/ int a,c; /* 分子*/ int sign,sign2,sign3,sign4; int yakusu,yakusu2,yakusu3,yakusu4; /* 最大公約数*/ printf("分母= "); scanf("%d",&b); printf("分子= "); scanf("%d",&a); if(b==0){ printf("分母が0です。入力が誤っています。\n"); /*分母が0ならエラーとする*/ return 0; } if (a==0){ printf("分数1= 0\n"); /*分子が0のとき*/ } else{ printf("分数1=%d|%d\n",a,b); /*一つ目の分数*/ } printf("\n"); printf("分母= "); scanf("%d",&d); printf("分子= "); scanf("%d",&c); if(d==0){ printf("分母が0です。入力が誤っています。\n"); /*分母が0ならエラーとする*/ return 0; } if (c==0){ printf("分数2= 0\n"); /*分子が0のとき*/ } else{ printf("分数2=%d|%d\n",c,d); /*二つ目の分数*/ } printf("\n"); /* 足し算:a|b + c|d = (a*d + b*c) | (b*d) */ printf("足し算:%d|%d + %d|%d\n",a,b,c,d); yakusu = gcd(abs(a*d + b*c),abs(b*d)); /*最大公約数を求める*/ sign = (a*d + b*c)/abs(a*d + b*c) * (b*d/abs(b*d)); if(sign * abs(a*d + b*c)/yakusu == 0){ /*分子が0となる時*/ printf("0\n"); } if (abs(b*d)/ yakusu!= 1){ printf("既約分数は %d|%d\n" ,sign * abs(a*d + b*c)/yakusu , abs(b*d)/yakusu ); } else{ printf("既約分数は %d\n" ,sign * abs(a*d + b*c)/yakusu ); /*分母が1の場合*/ } printf("\n"); /* 引き算:a|b - c|d = (a*d - b*c) | (b*d) */ printf("引き算:%d|%d - %d|%d\n",a,b,c,d); yakusu2 = gcd(abs(a*d - b*c),abs(b*d)); /*最大公約数を求める*/ sign2 = (a*d - b*c)/abs(a*d - b*c) * (b*d/abs(b*d)); if(sign2 * abs(a*d - b*c)/yakusu2 == 0){ /*分子が0となる時*/ printf("0\n"); } if (abs(b*d)/ yakusu2!= 1){ printf("既約分数は %d|%d\n" ,sign2 * abs(a*d - b*c)/yakusu2 , abs(b*d)/yakusu2 ); } else{ printf("既約分数は %d\n" ,sign2 * abs(a*d - b*c)/yakusu2 ); } printf("\n"); /* 掛け算:a|b * c|d = (a*c) | (b*d) */ printf("掛け算:%d|%d * %d|%d\n",a,b,c,d); yakusu3 = gcd(abs(a*c),abs(b*d)); /*最大公約数を求める*/ sign3 = (a*c)/abs(a*c) * (b*d/abs(b*d)); if(sign3 * abs(a*c)/yakusu3 == 0){ /*分子が0となる時*/ printf("0\n"); } if (abs(b*d)/ yakusu3!= 1){ printf("既約分数は %d|%d\n" ,sign3 * abs(a*c)/yakusu3 , abs(b*d)/yakusu3 ); } else{ printf("既約分数は %d\n" ,sign3 * abs(a*c)/yakusu3 ); /*分母が1の場合*/ } printf("\n"); /* 割り算:a|b / c|d = (a*d) | (b*c) */ printf("割り算:%d|%d / %d|%d\n",a,b,c,d); yakusu4 = gcd(abs(a*d),abs(b*c)); /*最大公約数を求める*/ sign4 = (a*d)/abs(a*d) * (b*c/abs(b*c)); if(sign4 * abs(a*d)/yakusu4 == 0){ /*分子が0となる時*/ printf("0\n"); } if (abs(b*c)/ yakusu4!= 1){ printf("既約分数は %d|%d\n" ,sign4 * abs(a*d)/yakusu4 , abs(b*c)/yakusu4 ); } else{ printf("既約分数は %d\n" ,sign4 * abs(a*d)/yakusu4 );/*分母が1の場合*/ } return 0; } int gcd(int x,int y){ /* ユークリッド互除法*/ int z; if( (x <= 0) || (y <= 0) ){ return -1; } z = x % y; while (z != 0){ x = y; y = z; z = x % y; } return y; } >>大学の課題です。現在の状態は上記の通りです。このプログラムだと、答えの既約分数が0になると表示できなかったり、桁が大きい数で計算しようとすると値がおかしくなってしまいます。 どなたかプログラム改良にご助力願えないでしょうか?

  • 最大公約数に関する問題です。

    最大公約数に関する問題です。 『2つの整数6186と4709の最大公約数(6189,4709)を求めよ。また、この最大公約数に対して、(6189,4709) = 6186X + 4709YとなるX,Yを見つけよ。』という問題です。最大公約数は1と求められたのですが、後半の『(6189,4709) = 6186X + 4709YとなるX,Yを見つけよ。』は、X,Y の組み合わせが無数にあると思うのですが、どうしたら良いのでしょうか?宜しくお願い致します。

  • 整式の割り算

    問題は次の(A)(B)を同時にみたす5次式f(x)を求めよ。図のような記述(赤○からの記述の後) (A)f(x)+8は(x+1)^3で割り切れる(B)f(x)-8は(x-1)^3で割り切れる 「f‘(x)は(x+1)^2で割り切れ、(x-1)^2でも割り切れる4次式である。」とあります。 整式の割り算で疑問に思ったのですが、なぜ(x-1)^2、(x+1)^2で割り切れるのでしょうか? (x-1)^3、(x+1)^3では割り切れないとはなぜいえないのでしょうか? 整式の割り算で A(x)=p(x)(割る式)q(x)(商)+r(x)と除法を考えるとき、r(x)の次数についてp(x)よりは低いということはわかるのですが。 整数の割り算ではA=P(割る数)Q(商)+R(あまり) Rについて0≦R<Pです。また、A,P,Q,Rはすべて整数になるよう考える。

  • 分数のかけ算、わり算

    採点者にもよると思いますが、 分数のかけ算、わり算の場合、仮分数から帯分数になおしては間違いなのでしょうか。解答を見ると加法、減法の場合のみ仮分数から帯分数になおした結果になってます。

専門家に質問してみよう