
(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)の部分のやり方がいまいちよくわからなかったので質問しました。
どなたかご教授お願いできないでしょうか・・・。
No.5ベストアンサー
- 回答日時:
/*
暗に結構コード書いて下さい、って丸投げする質問者ってのも多いんだけど, 質問者さんはそうじゃないみたいで安心した。
きっとこんなコードも読めるんじゃないかな?
*/
#include <stdio.h>
#include <math.h>
/*
abs(x)はxの絶対値を返す関数で,math.hに定義されているんだよ。
もしこれがなくても自分で作れると思う。
*/
int main(void){
int denominator; /* 分母の絶対値 */
int numerator; /* 分子の絶対値 */
int sign;
int gcdofthetwo;
printf("denominator = ");
scanf("%d",&denominator);
printf("numerator = ");
scanf("%d",&numerator);
if(denominator==0){
printf("error : denominator should not be 0. program will exit.\n");
return 0;
}
if (numerator==0){
printf("0");
return 0;
}
gcdofthetwo = gcd(abs(numerator),abs(denominator));
/*
numerator * denominatorがオーバーフローするかも、っていうのが怖いから
(numerator * denominator) / (abs(numerator) * abs(denominator))
って書かずにそれぞれ分割しているんだ
*/
sign = (numerator / abs(numerator)) * (denominator / abs(denominator));
/* 前回のコードで忘れてた最大公約数*/
printf ("gcd:%d\n", gcdofthetwo);
if (abs(denominator) / gcdofthetwo != 1){
printf("answer:%d / %d\n" ,sign * abs(numerator) / gcdofthetwo , abs(denominator) / gcdofthetwo );
}else{
printf("answer:%d\n" ,sign * abs(numerator) / gcdofthetwo );
}
}
int gcd(int a,int b){
/* ユークリッド互除法 */
int retval;
if( (a <= 0) || (b <= 0) ){
return -1;
}
retval = a % b;
while (retval != 0){
a = b;
b = retval;
retval = a % b;
}
return b;
}
2つもプログラムを書いて頂いて恐縮です。
上記のプログラムを見て、書き方が違うだけでとてもシンプルにまとめられるのだなぁと感じ、とても勉強になりました。
課題のほうも無事終えることができました。分かりやすい説明やプログラムまで書いてもらって、今回は本当にお世話になりました。有難うございます。
No.6
- 回答日時:
#5を修正
最初戻り値にするつもりでretvalって変数用意したんだけど
return b;って書いているから変数名がおかしい。
ので,変数名はremainderあたりのほうがいいと思う
No.4
- 回答日時:
>#1お礼
if (sign = 1)
と
if (sign == 1)
の違い解る?
if (sign = 1)
と
if (sign == 1)
の違い解る?
>>そういえば忘れていました・・・。
if文の条件を表す部分で「=(等しい)」を表すには「==」と書く、という決まりあったような。以後は気をつけます。
No.3
- 回答日時:
コード修正
if ( rawnumerator / rawdenominator < 0){
を
if ( (double)rawnumerator / (double)rawdenominator < 0){
に
No.2
- 回答日時:
全体の流れはこんな感じでしょうか。
・aとbを入力
・bが0ならエラー表示
・aとbの符号が異なるか調べて符号用変数をセット
→ (aが負)かつ(bがゼロか正)、または、(aが正かゼロ)かつ(bが負)なら符号が異なる(0は正の扱いとしておく)
→符号が異なるときは符号用変数を-1、符号が同じなら0をセット
・以降の計算は、aもbも正数にして行なう。
・約分の計算(分子と分母を最大公約数で割る)
・符号用変数が-1なら分子をマイナスにする。
・分母が1なら分子だけ表示、そうでなければ分子と分母を表示
No.1
- 回答日時:
/*
質問文をベースを活かすと効率は悪いがこうなる。
変数名変えまくっている。
表示内容を英語にしているのは,書いているのがUTF-8のコードで
gccでコンパイルして
コマンドプロンプト(Shift_JIS)で日本語表示すると化けるから
質問文と違い, 分母 = 2,分子 = 4を入力した場合 4/2ではなく 2と表示する。
質問文と違い, 分母 = 0,分子 = 4を入力した場合 0/4ではなく 0と表示する。
効率的にやるなら
公約数を求める部分を別な関数に分けるし,
math.hを利用してabs関数を用いたりする。
三項演算子も使うかもしれない
*/
#include <stdio.h>
int main(void){
int rawdenominator; /* 分母 */
int rawnumerator; /* 分子 */
int absdenominator; /* 分母の絶対値 */
int absnumerator; /* 分子の絶対値 */
int i; /* カウンタ */
int gcd; /* 分母の絶対値と分子の絶対値の公約数 */
int sign;
printf("denominator = ");
scanf("%d",&rawdenominator);
printf("numerator = ");
scanf("%d",&rawnumerator);
if(rawdenominator==0){
printf("error : denominator should not be 0. program will exit.\n");
return 0;
}
if (rawnumerator==0){
printf("0");
return 0;
}
if (rawnumerator < 0){
absnumerator = -rawnumerator;
}else{
absnumerator = rawnumerator;
}
if (rawdenominator < 0){
absdenominator = -rawdenominator;
}else{
absdenominator = rawdenominator;
}
if (rawnumerator / rawdenominator < 0){
sign = -1;
}else{
sign = 1;
}
i = 1;
gcd = 1;
while((i<=absnumerator)&&(i<= absdenominator)){
if((absnumerator % i==0) && (absdenominator % i==0)){
gcd=i;i=i+1;
}else{
i=i+1;
}
}
if (gcd == absdenominator){
if (sign >= 0){
printf("%d",absnumerator / absdenominator);
}else{
printf("- %d",absnumerator / absdenominator);
}
return 0;
}else{
if (sign >= 0){
printf("%d / %d",absnumerator / gcd ,absdenominator / gcd);
}else{
printf("- %d / %d",absnumerator / gcd ,absdenominator / gcd);
}
return 0;
}
}
わざわざ長いプログラムまで書いてもらってお手数をおかけしました。とても勉強になりました。
1つ質問があるのですが
・
・
if (gcd == absdenominator){
if (sign >= 0){
printf("%d",absnumerator / absdenominator);
}else{
printf("- %d",absnumerator / absdenominator);
}
return 0;
・
・
場合わけの部分でif (sign >= 0)となっていますがif (sign =1)とするとうまく表示されなくなりました。ソース上ではsignは1か-1のどちらかなので>=0を=1にしてもいいのではと考えたのですが・・・。何か理由があるのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コンパイルエラーについて
-
構造体メンバの個数
-
scanfに文字が入力されたときに...
-
アドレスの比較について
-
三角形の判別
-
3つの入力した数値の大小比較...
-
getchar()マクロによる空白文字...
-
C言語についてです学籍番号、名...
-
文字と数字の判定について
-
c言語 プログラム ピラミッド
-
wsprintf関数(書式制御文字列...
-
printf( " %2d", p * q );
-
C言語に関する質問です
-
printf で二進表示を行いたい。
-
Cプログラミングのアルゴリズム...
-
LU分解法のピボット選択機能実...
-
現在時刻の表示について
-
C言語に関して質問です。 次の...
-
c言語で2000年以降カレンダーを...
-
C言語の勉強しています。すみま...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
10個出力で改行したいのですが...
-
c言語でAからZまでを表示する...
-
(C言語)めちゃくちゃな値にな...
-
コマンドラインに出力した文字...
-
コンパイルエラーについて
-
コマンドプロンプトがすぐ消える
-
勝率をプログラムに
-
テキストカーソル位置の取得
-
三角形の判別
-
【C言語教えてください】sin波...
-
4の倍数を論理演算で表す。。
-
C言語で、「自然数nを入力し、n...
-
入力したお金の金額からお札の...
-
cshの文字列操作(0埋め)
-
switch分のケースを範囲数?に...
-
scanfに文字が入力されたときに...
-
プログラミングについての質問です
-
unsigned int型について
-
ダブルポインタで2次元配列を作成
-
円の面積を求めるプログラミン...
おすすめ情報