Не сокращаются дроби

253
04 августа 2021, 03:00

Вот код работает более-менее правильно только не сокращаются дроби. Как это пофиксить?

#include <iostream>
class fraction {
    int num;
    int den;
public:
    fraction() :num(0), den(1) {};
    fraction(int a, int b) :num(a), den(b) {};
    fraction putfrac() {
        std::cout << "Введите дробь ";
        std::cin >> num;
        std::cin.ignore();
        std::cin >> den;
        return fraction(num, den);
    }
    void display() {
        if (den == 0) {
            std::cout << "!!!Ошыбка!!!";
            exit(1);
        }
        std::cout << num << "/" << den << std::endl;
    }
    fraction reduce() {
        int i;
        int nod;
        for (i = num; i > 0; i--) {
            if (num % i == 0 && den % i == 0) {
                nod = i; break;
            }
        }
        num /= nod;
        den /= nod;
        return fraction(num, den);
    }
    fraction operator+ (fraction f1) {
        int a = num * f1.den + f1.num * den;
        int b = den * f1.den;
        return fraction(a, b);
    }
    fraction operator- (fraction f1) {
        int a = num * f1.den - f1.num * den;
        int b = den * f1.den;
        return fraction(a, b);
    }
    fraction operator* (fraction f1) {
        int a = num * f1.num;
        int b = den * f1.den;
        return fraction(a, b);
    }
    fraction operator/ (fraction f1) {
        int a = num * f1.den;
        int b = den * f1.num;
        return fraction(a, b);
    }
};
int main()
{
    setlocale(LC_ALL, "russian");
    char ch;
    fraction a, b, c;
    a.putfrac();
    b.putfrac();
    std::cout << "Выберете операцию: ";
    std::cin >> ch;
    switch (ch)
    {
    case '+': { c = a + b;  break; }
    case '-': {c = a - b; break; }
    case '*': {c = a * b; break; }
    case '/': {c = a / b; break; }
    default: {std::cout << "Ошыбка!!!"; }
    };
    c.reduce();
    std::cout << "Результат: ";
    c.display();
    return 0;
}
Answer 1

Не сокращает где? При putfrac()? Но ведь вы там и не пытаетесь сокращать!

Кстати, я бы просто сделал reduce() функцией, вызываемой в нужные моменты (в конструкторе, в putfrac() и т.д.), которая ничего не возвращает, а просто преобразует имеющуюся дробь (какой глубокий смысл в возврате ею значения?)

fraction() :num(0), den(1) {};
fraction(int a, int b) :num(a), den(b) { reduce(); };
void putfrac() {
    std::cout << "Введите дробь ";
    std::cin >> num;
    std::cin.ignore();
    std::cin >> den;
    reduce();
}

Кроме того, так неэффективно сокращать дробь - надо постараться... Ведь еще классе в 5-6 учат наибольший общий делитель. Так что ваш код я бы записал так:

void fraction::reduce() {
    int d = gcd(num,den);
    num /= d;
    den /= d;
}

Если компилятор староват и не знает, что такое gcd - он пишется в две строки:

int gcd(int m, int n)
{
    while(m && n) if (m < n) n %= m; else m %= n;
    return m + n;
}

И исправьте слово "Ошибка" - в русском языке после "ш" пишется "и". Глаза ведь режет...

READ ALSO
Не могу разобраться с записью указателя на функцию С++

Не могу разобраться с записью указателя на функцию С++

Объясните, что это за мура? Вроде как указатель на функцию, знак равенства сбивает с толку, не видел такой записи

195
left operand must be l-value

left operand must be l-value

Я хочу неизвестному типу указателя присвоить void *, те

336
Веб доступ к десктопному приложению

Веб доступ к десктопному приложению

Объясню суть проблемы: есть десктопное графическое приложение ,написанное на с++, появилась срочная необходимость доступа к нему через web браузер,...

155