C++のエラーについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
C++はじめました

C++のエラーについて

#1

投稿記事 by C++はじめました » 8年前

このソースなのですが、
入力値、3/4と1/2を入力したときに、
引き算の箇所が答えにならないのですが、どうしたらよいでしょうか。
数値によっては正しい答えが出てくるのですが・・・

コード:

#include <iostream>
using namespace std;
class Frac {
protected:
	int bunshi, bunbo;
	int gcd(int a, int b) {
		int p;
		if (a < b)p = b;
		else p = a;
		while (1) {
			if (a%p == 0 && b%p == 0) {
				return p;
				cout << p << endl;
			}
			p--;
		}
		return 0;
	}
public:
	Frac(int a, int b) {
		bunshi = a;
		bunbo = b;
		gcd(bunbo, bunshi);
		int yaku;
		yaku = gcd(bunshi, bunbo);
		if (yaku == 0) {
			return;
		}
		else {
			bunshi = bunshi / yaku;
			bunbo = bunbo / yaku;
		}
	}

	void print() {

		if (bunbo == 1) {
			cout << bunshi << endl;
		}
		else if (bunshi > bunbo) {
			cout << bunshi / bunbo << " + (" << bunshi % bunbo << "/" << bunbo << ")" << endl;
		}
		else {
			cout << "(" << bunshi << "/" << bunbo << ")" << endl;
		}
	}
	Frac operator*(Frac b) {
		int shi = bunshi* b.bunshi;
		int bo = bunbo* b.bunbo;
		return Frac(shi, bo);
	}
	Frac operator/(Frac b) {
		int shi = bunshi * b.bunbo;
		int bo = bunbo * b.bunshi;
		return Frac(shi, bo);
	}
	Frac  operator+(Frac b) {
		int aa = gcd(bunbo, b.bunbo);
		int bb = (bunbo*b.bunbo) / aa;
		int c = 1;
		int d = bunbo;
		while (bb != bunbo) {
			bunbo += d;
			c++;
		}
		bunshi *= c;
		c = 1;
		d = b.bunbo;
		while (bb != b.bunbo) {
			b.bunbo += d;
			c++;
		}
		b.bunshi *= c;
		return Frac(bunshi + b.bunshi, bunbo);

	}
	Frac operator-(Frac b) {
		int shi = bunshi - b.bunshi;
		return Frac(shi, b.bunbo);
	}
};
int main() {
	int h, m;
	cin >> h >> m;
	Frac a1 = Frac(h, m);
	a1.print();

	cin >> h >> m;
	Frac a2 = Frac(h, m);
	a2.print();

	Frac b = a1*a2;
	b.print();

	b = a1 / a2;
	b.print();

	b = a1 + a2;
	b.print();

	b = a1 - a2;
	b.print();
	return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C++のエラーについて

#2

投稿記事 by みけCAT » 8年前

足し算は複雑でよくわからないが通分を実装している?のに、引き算では通分を実装せずに分母を2番目の分数のもので決め打ちしてしまっているので、
きちんと引き算でも通分をして計算するコードに書き換えるといいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C++のエラーについて

#3

投稿記事 by みけCAT » 8年前

足し算のコードでは1番目の分数は直接書き換えているのに対し、2番目の分数は引数として渡されたコピーを書き換え、元のデータは保存する仕様になっており、不自然なので、
足し算で1番目の分数も書き換えるのをやめて、引き算でも非破壊的な通分を実装する(推奨)か、
常に引き算の前に足し算をすると仮定して、引き算のコードはそのままにし、足し算の引数を参照にして2番目の分数も書き換えるようにする(非推奨)と、
このプログラムの出力は改善するでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

C++はじめました

Re: C++のエラーについて

#4

投稿記事 by C++はじめました » 8年前

具体的なソースを教えていただけるとありがたいです…
よろしくお願いします

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C++のエラーについて

#5

投稿記事 by みけCAT » 8年前

掛け算や割り算と書き方を合わせるなら

コード:

	Frac operator+(Frac b) {
		int shi = bunshi* b.bunbo + b.bunshi* bunbo;
		int bo = bunbo* b.bunbo;
		return Frac(shi, bo);
	}
	Frac operator-(Frac b) {
		int shi = bunshi * b.bunbo - b.bunshi * bunbo;
		int bo = bunbo * b.bunbo;
		return Frac(shi, bo);
	}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

C++はじめました

Re: C++のエラーについて

#6

投稿記事 by C++はじめました » 8年前

なるほど!!!
出来ました。ありがとうございます。
もう一つなんですけど、

このソースで、Fracを継承して、
整数との掛け算*と、整数との割り算/を定義したいのですが、
どうしたらよいのでしょうか....汗

コード:

#include <iostream>
using namespace std;
class Frac {
protected:
	int bunshi, bunbo;
	int gcd(int a, int b) {
		int p;
		if (a < b)p = b;
		else p = a;
		while (1) {
			if (a%p == 0 && b%p == 0) {
				return p;
				cout << p << endl;
			}
			p--;
		}
		return 0;
	}
public:
	Frac(int a, int b) {
		bunshi = a;
		bunbo = b;
		gcd(bunbo, bunshi);
		int yaku;
		yaku = gcd(bunshi, bunbo);
		if (yaku == 0) {
			return;
		}
		else {
			bunshi = bunshi / yaku;
			bunbo = bunbo / yaku;
		}
	}

	void print() {

		if (bunbo == 1) {
			cout << bunshi << endl;
		}
		else if (bunshi > bunbo) {
			cout << bunshi / bunbo << " + (" << bunshi % bunbo << "/" << bunbo << ")" << endl;
		}
		else {
			cout << "(" << bunshi << "/" << bunbo << ")" << endl;
		}
	}
	Frac operator*(Frac b) {
		int shi = bunshi* b.bunshi;
		int bo = bunbo* b.bunbo;
		return Frac(shi, bo);
	}
	Frac operator/(Frac b) {
		int shi = bunshi * b.bunbo;
		int bo = bunbo * b.bunshi;
		return Frac(shi, bo);
	}
	Frac operator+(Frac b) {
        int shi = bunshi* b.bunbo + b.bunshi* bunbo;
        int bo = bunbo* b.bunbo;
        return Frac(shi, bo);
    }
    Frac operator-(Frac b) {
        int shi = bunshi * b.bunbo - b.bunshi * bunbo;
        int bo = bunbo * b.bunbo;
        return Frac(shi, bo);
    }
};


class Frac2:public Frac{
public:

};


int main()
{
 int a, b;
 cin >> a >> b;
 Frac2 f1 = Frac2(a, b);
 f1.print();
 int n;
 cin >> n;
 Frac2 f2 = f1 * n;
 f2.print();
 f2 = f1 / n;
 f2.print();
 return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C++のエラーについて

#7

投稿記事 by みけCAT » 8年前

C++はじめました さんが書きました:このソースで、Fracを継承して、
整数との掛け算*と、整数との割り算/を定義したいのですが、
どうしたらよいのでしょうか....汗
定義するコードを書けばいいと思うのですが、何がわからないのでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: C++のエラーについて

#8

投稿記事 by かずま » 8年前

C++はじめました さんが書きました:このソースで、Fracを継承して、
整数との掛け算*と、整数との割り算/を定義したいのですが、
どうしたらよいのでしょうか....汗
継承を使わないから、解答ではありませんが、
Frac のコンストラクタを次のようにすると、

コード:

    Frac(int a = 0, int b = 1) {
Frac に整数を掛けたり、割ったりできるようになります。

コード:

 Frac f1 = Frac(a, b);
   :::
 Frac f2 = f1 * n;
 f2.print();
 f2 = f1 / n;

かずま

Re: C++のエラーについて

#9

投稿記事 by かずま » 8年前

かずま さんが書きました:Frac に整数を掛けたり、割ったりできるようになります。
日本語がおかしいので次のように訂正します。
Frac に整数を掛けたり、Frac を整数で割ったりできるようになります。

これだけでは何なので、元のプログラムの変なところを指摘しておきます。
  • 13行目の cout << p << endl; は、return p; の後なので実行されません。
  • 17行目の return 0; は、while ループを return p; で抜けているので実行されません。
  • gcd のアルゴリズムは、非効率です。
  • 23行目の gcd(bungo, bunshi); は結果をどこにも保存しないので無意味です。

返信

“C言語何でも質問掲示板” へ戻る