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になると表示できなかったり、桁が大きい数で計算しようとすると値がおかしくなってしまいます。
どなたかプログラム改良にご助力願えないでしょうか?
お礼
なるほど! わかりました。 ご丁寧に例まで書いていただき、ありがとうございます。