Перегруженные операторы C++: почему знаменатель умножается на 10

Я работаю над дробным заданием, где я предлагаю пользователю две дроби, затем я складываю, вычитаю, умножаю и делю две дроби. Я знаю, что мне все еще нужно сокращать дроби, однако я не могу понять, почему знаменатели умножаются на 10. Если я введу 1 1/2 для frac1 и 2 2/5 для frac2, знаменатель будет 100 вместо 10 , Так странно .. любое руководство приветствуется! :)

// fraction9.cpp : main project file.
#include "stdafx.h"
#include<conio.h>
#include<iostream>
 #include<string>
using namespace std;


class Fraction
{
private:
   int whole;
   int numerator;       // may be any integer
   int denominator;     // should always be positive
public:
 Fraction();    // Set numerator = 0, denominator = 1.
 Fraction(int w, int n, int d=1);   // constructor with parameters
            //  acts as conversion constructor

 // operator overload as member
 Fraction operator+ (const Fraction& f) const; 
 Fraction operator- (const Fraction& f) const;
 Fraction operator* (const Fraction& f) const;
 Fraction operator/ (const Fraction& f) const;     

 // standard input/output routines
 void Input();      // input a fraction from keyboard.
 void Show() const;     // Display a fraction on screen

 // accessors
 int GetWhole() const;
 int GetNumerator() const;
 int GetDenominator() const;

 // mutator
   bool SetValue(int w, int n, int d=1); // set the fraction's value through parameters
   //double Evaluate() const;   // Return the decimal value of a fraction


};

Fraction Fraction::operator+(const Fraction& f) const
// operator overload for + written as member function
{
   Fraction r;      // result
   r.numerator = (denominator * whole + numerator) * f.denominator + (f.denominator *     f.whole + f.numerator) * denominator;
   r.denominator = (denominator * f.denominator);
   return r;
}

Fraction Fraction::operator-(const Fraction& f) const
// operator overload for - written as member function
{
   Fraction r;      // result
   r.numerator = (denominator * whole + numerator) * f.denominator - (f.denominator *     f.whole + f.numerator) * denominator;
   r.denominator = (denominator * f.denominator);
   return r;
}

// operator overload for * written as member function
Fraction Fraction::operator*(const Fraction& f) const
{
   Fraction r;      // result
   r.numerator = ((denominator * whole + numerator) * (f.denominator * f.whole +     f.numerator));
   r.denominator = (denominator * f.denominator);
   return r;
}

// operator overload for / written as member function
Fraction Fraction::operator/(const Fraction& f) const
{
   Fraction r;      // result
   r.numerator = ((denominator * whole + numerator) * f.denominator);
   r.denominator = (denominator * (f.denominator * f.whole + f.numerator));
   return r;
}

Fraction::Fraction()
// Default constructor.  Initializes fraction to 0/1
{
   whole = 0;
   numerator = 0; 
   denominator = 1;
}

Fraction::Fraction(int w, int n, int d)
// initializes fraction to n/d (defaults to 0/1 if invalid data)
{
   if (SetValue(w, n, d) == false)
  SetValue(0, 0, 1);
}

void Fraction::Input()
{
    cout << "Enter whole number ";
  cin >> whole;
  cout << "Enter numerator " ;  
  cin >> numerator; 
  cout << "Enter denominator ";
  cin >> denominator;
      if (denominator <= 0)
  cout << "*** Denominator must be positive.  Try again: ";
  while (denominator <= 0)
    {
        cout << "Please re-enter the denominator of the fraction, it cannot be 0" <<     endl;
        cin >> denominator;
    };
}

void Fraction::Show() const
// Display a fraction
{
   cout << whole << " " << numerator << '/' << denominator;
}

int Fraction::GetWhole() const
{
    return whole;
}

int Fraction::GetNumerator() const
{
   return numerator;
}

int Fraction::GetDenominator() const
{
   return denominator;
}

bool Fraction::SetValue(int w, int n, int d)
// sets fraction to n/d and returns true for success (good data)
// returns false and leaves fraction alone if bad data
{
   if (d <= 0)
    return false;

   numerator = n;
   denominator = d;
   return true;
}

// Driver routine to test the Fraction class 

int main()
{

Fraction f1, f2;
cout << "Enter first fraction: ";
f1.Input();
cout << "\n You entered ";
f1.Show();
cout << "\n Enter second fraction: ";
f2.Input();
cout << "You entered ";
f2.Show();
cout << "\n The sum of the first and second fraction is ";
Fraction Aresult;
Aresult = f1 + f2;
Fraction Sresult;
Sresult = f1 - f2;
Fraction Mresult;
Mresult = f1 * f2;
Fraction Dresult;
Dresult = f1 / f2;
Aresult.Show();
Sresult.Show();
Mresult.Show();
Dresult.Show();
cout << '\n';
_getch();
return 0;

}

person Amanda Brine    schedule 21.10.2012    source источник
comment
Я смотрю прямо сейчас, если кто-то не ответит первым.   -  person M4rc    schedule 21.10.2012
comment
Вы не выводите новые строки между вызовами Show?   -  person aschepler    schedule 21.10.2012
comment
Ваша математика (и общая логика) подтверждается тем, чего она стоит. Однако сообщение об ошибке при втором вводе отрицательного знаменателя немного сбивает с толку. Кроме того, вы можете добавить проверку на деление на 0.   -  person Cameron    schedule 21.10.2012
comment
Просто в качестве предупреждения о том, как я тестировал, с вашими числами (и добавлением новых строк между вызовами show) я получаю правильные дробные выходные данные 39/10 -9/10 36/10 и 15/24. То, как вы получаете 100 в качестве знаменателя, кажется особой проблемой. Тем не менее, я не видел объявления оператора (по крайней мере, не просматривая его), которое возвращает значение, а не возвращает *this.   -  person M4rc    schedule 21.10.2012
comment
Обратите внимание, что код не приводится к самым низким условиям, поэтому ожидаются дополнительные факторы.   -  person Raymond Chen    schedule 21.10.2012


Ответы (1)


Эти дополнительные нули не добавляются к знаменателям. Это целые части смешанных дробей, которые вы связываете вместе.

Результаты на самом деле

0 39/10
0 -9/10
0 36/10
0 15/24

но вы печатаете их в одной строке:

0 39/100 -9/100 36/100 15/24
person Beta    schedule 21.10.2012
comment
Это объясняет, почему у меня не было проблем с моим тестом, я (для удобочитаемости) поставил cout<<endl; между отпечатками. - person M4rc; 21.10.2012