(整数値)aの値と(整数値)bの値をキーボードから入力して、そこから、a/bという分数を作るプログラムを書きたいと思います。(符号や約分も考えた形にする)
僕は、ヒントを参考に以下のようなプログラムを書いたのですが、ある条件の下では、正しく動きません。
・aの値が負の場合
・aもbも負の値の場合 など・・・
#include <stdio.h>
#include <math.h>
int main ( void )
{
int a,b;
int k,min,sign;
printf("a=?");scanf("%d",&a);
printf("b=?");scanf("%d",&b);
if (a*b<0) sign = -1;
elsesign = 1;
a = sign*a ; b = sign*b;
if (abs(a)>abs(b)) min = b;
else min = abs(a);
for ( k=2 ; k<=min ; k++){
if (min%k == 0){
a = a/k;
b = b/k;
}
}
printf("a/b = %d",a);
if (b != 1)
printf("/%d\n",b);
else printf("\n");
return 0;
}
これをどのように修正すれば、正確な答えが出るのでしょうか?
教えてください。
No.10
- 回答日時:
#include <stdio.h>
#include <stdlib.h>
int GCD(int a, int b)
{
if(!b) return a;
return GCD(b, a % b);
}
int main(void)
{
int a, b, sign, gcd;
char *signc[] = {"", "-",};
scanf("%d %d", &a, &b);
if(!b) puts("Error");
else if(!a) puts("0");
else{
sign = (a < 0) ^ (b < 0);
a = abs(a);
b = abs(b);
gcd = GCD(a, b);
printf("%s%d/%d\n", signc[sign], a / gcd, b / gcd);
}
return 0;
}
No.9
- 回答日時:
★回答者 No.5、6、8です。
→訂正・約分の for ループ内に一箇所、記述ミスがありました。
間違い⇒if ( !(a % k) && !(b & k) ){
正しい⇒if ( !(a % k) && !(b % k) ){
※『&』文字を『%』文字に修正して下さい。
以上です。
No.8
- 回答日時:
★そうですね。
>b = 0の時は不能ですが,
>bが0でなくa = 0の時は、0が表示されるべきです。
でも、それならば 0 で割ったときは『無限大』とか、『ゼロ除算エラー』とか表示するのもありですね。
・数学では 0 で割ると『商』は無限大になります。
123 ÷ 0.1 = 1230
123 ÷ 0.01 = 12300
123 ÷ 0.001 = 123000
123 ÷ 0.0001 = 1230000
123 ÷ 0.000…001 = 1230000…000(無限大)
↑
このことから限りなく 0 に近い数で割ると無限大となります。
電卓ではエラー、ゼロ除算エラーまたはオーバーフローとして最大値など表示されます。
・以上。
No.6
- 回答日時:
★追記。
・符号の判定はオーバーフローや int 型が 16、32ビットにも対応するように
次のようにするのも良いでしょう。
// マクロ関数
#define GetSign(a) (((a) < 0) ? -1 : ((a) > 0) ? +1 : 0)
// 3項演算子で符号を判定
sign = (GetSign(a) * GetSign(b));
↑
これが分数全体の符号です。
・この sign には -1、+1、0 が入ります。
もし 0 ならば入力をやり直すようにも使えます。
つまり、
// a、b を入力
do {
printf( "a=?" ); scanf( "%d", &a );
printf( "b=?" ); scanf( "%d", &b );
// 3項演算子で符号を判定
sign = (GetSign(a) * GetSign(b));
} while ( sign == 0 );
↑
これで a、b が 0 以外ならば do-while を抜けます。
・以上。
No.5ベストアンサー
- 回答日時:
★アドバイス
・まずは算数からアドバイスします。
- - ⇒+
- + ⇒-
+ - ⇒-
+ + ⇒+
ですよね。
・だから入力された a、b の符号から分数全体の sign を処理します。
その後に a、b の2つの値を強制的に絶対値にします。→abs()関数で。
・あとは 2 から順に a、b のどちらかの小さい数まで約分を行います。
このときに a、b の両方が割り切れるかをチェックします。
両方が割り切れたときに割り算を行います。
・約分まで終わったら分数の形で表示して処理終了です。
それではサンプルを載せますので見比べて下さい。
サンプル:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
int a, b, k, min, sign;
// a、b を入力
printf( "a=?" ); scanf( "%d", &a );
printf( "b=?" ); scanf( "%d", &b );
// 3項演算子で符号を判定
sign = (((a * b) < 0) ? -1 : +1);
// 強制的に絶対値に変換
a = abs( a );
b = abs( b );
min = ((a < b) ? a : b);
// 約分
for ( k = 2 ; k <= min ; k++ ){
if ( !(a % k) && !(b & k) ){ ←a、bのが両方割り切れるか判定
a /= k;
b /= k;
}
}
// 表示
if ( b == 1 ){
printf( "a/b = %+d\n", (sign * a) );
}
else{
printf( "a/b = %+d/%d\n", (sign * a), b );
}
return 0;
}
最後に:
・分数全体の符号は表示する部分で掛け算すれば楽です。
あと a、b のどちらか一方が 0 だった場合の処理を追加してみて下さい。
回答者 No.4 さんの『do { … } while ( !(a | b) );』のやり方で入力を繰り返すのが
一番スマートかなと思います。
以上。
参考URL:http://www9.plala.or.jp/sgwr-t/c/sec14.html
No.4
- 回答日時:
#include <stdio.h>
#include <math.h>
#define REV 0x80000000
int main ( void )
{
int a,b;
int k,min,max,sign;
char sign_ch;
do{
printf("a=?");scanf("%d",&a);
printf("b=?");scanf("%d",&b);
}while(!(a&b));
sign=(a&REV)|(b&REV)?-1:1;
a*=((a&REV)&&!(b&REV))?1:sign,b*=(b&REV)?-1:1;
if (abs(a)>abs(b)) min=b,max=abs(a);
else min=abs(a),max=b;
for ( k=2 ; k<=min ; k++){
while (!(a%k||b%k)){
a/=k;
b/=k;
printf("%d/%d,%d\r\n",a,b,k);
}
}
sign_ch=a&REV?'-':' ';
printf("a/b = %c%d",sign_ch,abs(a));
if (abs(b) != 1)
printf("/%d\n",abs(b));
else printf("\n");
return 0;
}
こんな感じでしょうか…。
No.3
- 回答日時:
あ、いけね。
手を抜きすぎた気がするsign = a/abs(a) * b / abs(b);
/*
でないと、a * bがオーバーフローするかもしれない
*/
/*
ついでに言うと、bが表示されないのは、
b=1の時だけではなく a=0の時もそう。(a % b = 0)
(俺のコードだとa = 0またはb = 0の時,0除算エラーが出る)
b = 0の時は処理を飛ばさなきゃいけない
ってことも忘れないようにしないとね!
*/
No.2
- 回答日時:
/*
バグっているかもしれないが元の奴よりもずっとマシなはず。
質問文のコード
min = abs(b);のつもりがmin = b;になってたよね(汗。
bが負でaがそれより大きいと、ループの終了条件にいきなりひっかかるんですけど。
*/
#include <stdio.h>
#include <math.h>
int commonfactor(int val1,int val2);
int main ( void )
{
int a,b;
int factor;
int sign;
printf("a=?");
scanf("%d",&a);
printf("b=?");
scanf("%d",&b);
factor = commonfactor(abs(a),abs(b));
sign = a * b / (abs(a) * abs(b));
b = abs(b)/factor;
a = sign * abs(a)/factor;
printf("a/b = %d",a);
if (b != 1)
{printf("/%d\n",b);}
else
{printf("\n");}
return 0;
}
int commonfactor(int val1,int val2)
{
/* バグっているかもしれないといったのは
ここで引数をabs関数にくぐらせず、呼び出し元でくぐらせた事 */
int i;
int maxfactor = 1;
int min;
if (val1 > val2)
{
min = val2;
}
else
{
min = val1;
}
/* でも多分実は最小値算出は不要。何故なら余りが0になることは無いから */
for (i = 2 ;i < min + 1;i++)
{
if ((val1 % i == 0) && (val2 % i == 0))
{
maxfactor = i;
}
}
return maxfactor;
}
No.1
- 回答日時:
#include <stdio.h>
#include <math.h>
/* 答えは言わないけど、考えてみよう*/
/*俺 if文この書き方じゃないと落ち着かないんだ。・・・*/
int main ( void )
{
int a,b;
int k,min,sign;
printf("a=?");scanf("%d",&a);
printf("b=?");scanf("%d",&b);
if (a*b<0)
{sign = -1;}
else
{sign = 1;}
a = sign*a ; b = sign*b;
if (abs(a)>abs(b))
{min = b;}
else
{min = abs(a);}
printf("min:%d\n",min);
for ( k=2 ; k<=min ; k++){
if (min % k == 0){ /* a = 15, b = 6の時どうなるかやってみると? */
a = a/k;
b = b/k;
printf("k:%d\n",k); /*ここを見よう!*/
printf("a:%d\n",a); /*ここを見よう!*/
printf("b:%d\n",b); /*ここを見よう!*/
printf("\n");
}
}
printf("a/b = %d",a);
if (b != 1)
printf("/%d\n",b);
else printf("\n");
return 0;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# 至急教えてください!プログラミングの問題です。 割られる整数と割る整数を受け取って、商と余りを出力す 3 2022/07/05 10:23
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
10個出力で改行したいのですが...
-
カレンダーのプログラムについて
-
4の倍数を論理演算で表す。。
-
【C言語教えてください】sin波...
-
CTRL+Dでループを抜けるには
-
C言語です このプログラミング...
-
じゃんけんゲームをつくったの...
-
printf( " %2d", p * q );
-
defineで定数が置き換えられな...
-
printf で二進表示を行いたい。
-
一番大きい奇数を表示する
-
万年カレンダーのC言語プログラ...
-
両替プログラムなど
-
C言語初心者です。次の問題で質...
-
C言語です
-
困ってます!Cプログラミングに...
-
(C言語)めちゃくちゃな値にな...
-
TeraPadの設定方法
-
じゃんけんゲームの応用
-
C言語のじゃんけんゲームのプロ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語について
-
printf で二進表示を行いたい。
-
cshの文字列操作(0埋め)
-
10個出力で改行したいのですが...
-
コンパイルエラーについて
-
テキストカーソル位置の取得
-
strcmp
-
unsigned int型について
-
c言語でAからZまでを表示する...
-
printf( " %2d", p * q );
-
コマンドラインに出力した文字...
-
printfの出力内の文字をdefine...
-
ホームページをC言語で作りたい...
-
コマンドプロンプトがすぐ消える
-
小数点切捨て表示
-
【C言語教えてください】sin波...
-
switch分のケースを範囲数?に...
-
二つの整数値の大小比較
-
4の倍数を論理演算で表す。。
-
defineで定数が置き換えられな...
おすすめ情報