• Paranoid - курс по анонимности и безопасности в сети от команды codeby. Защита персональных данных, анонимность в сети интернет, настройка виртуальных машин, безопасная передача данных, анти форензика и еще много всего полезного. Подробнее ...

Калькулятор С++ Обыкновенные Дроби В Двух Формах:

samich

New member
14.01.2012
1
0
#1
Обыкновенные дроби в
двух формах:
- числитель/
знаменатель;
- целая часть
числитель/знаменатель.


помогите исправить ошибку не получается чтоб калькулятор складывал умножал делил и вычитал всегда пишет 1 в ответе
C++:
#include <iostream>
#include <cmath>
#include <fstream>
#include <string>

class Rational
{
private:
int a, b;
void reduce();
public:
Rational();
Rational( int a0, int b0 );
explicit Rational( const Rational &r );
Rational& operator= ( const Rational &r );
void init( int a0, int b0 );
friend std::ostream& operator<< ( std::ostream &os, const Rational &rat );
friend std::istream& operator>> ( std::istream &is, Rational &rat );
Rational& operator+ ( Rational &r );
Rational& operator- ( Rational &r );
Rational& operator* ( Rational &r );
Rational& operator/ ( Rational &r );
Rational& operator^ ( int );
void swap();
friend void toLog( std::ifstream &f, std::string &msg, Rational &rat );
void exchangeSign();
};

void Rational::reduce()
{
int min, sign = 1;
if ( a < 0 && b < 0 )
{
a = -a;
b = -b;
}
else if ( a < 0 )
{
sign = -1;
a = -a;
}
else if ( b < 0 )
{
sign = -1;
b = -b;
}
min = ( a < b ) ? ( a ) : ( b );
for( int i = min; i >= 2; i-- )
if ( a % i == 0 && b % i == 0 )
{
a /= i;
b /= i;
}
a *= sign;
}

Rational::Rational( int a0, int b0 )
{
a = a0;
b = b0;
reduce();
}

Rational::Rational()
{
a = 0;
b = 1;
}

Rational::Rational( const Rational &r )
{
a = r.a;
b = r.b;
reduce();
}

void Rational::init( int a0, int b0 )
{
a = a0;
b = b0;
reduce();
}

std::ostream& operator<< ( std::ostream &os, const Rational &rat )
{
if ( rat.b == 1 || rat.a == 0 )
os << rat.a;
else os << rat.a << "/" << rat.b;
return os;
}

std::istream& operator>> ( std::istream &is, Rational &rat )
{
is >> rat.a >> rat.b;
return is;
}

Rational& Rational::operator= ( const Rational &r )
{
a = r.a;
b = r.b;
reduce();
return *this;
}

Rational& Rational::operator+( Rational &r )
{
Rational temp;
temp.a = r.a * b + a * r.b;
temp.b = r.b * b;
temp.reduce();
return temp;
}

Rational& Rational::operator- ( Rational &r )
{
Rational temp;
temp.a = a * r.b - b * r.a;
temp.b = b * r.b;
temp.reduce();
return temp;
}

Rational& Rational::operator* ( Rational &r )
{
Rational temp;
temp.a = a * r.a;
temp.b = b * r.b;
temp.reduce();
return temp;
}

Rational& Rational::operator/ ( Rational &r )
{
Rational temp;
temp.a = a * r.b;
temp.b = b * r.a;
temp.reduce();
return temp;
}

Rational& Rational::operator^ ( int deg )
{
Rational temp;
temp.a = a;
temp.b = b;
for( int i = 1; i < deg; ++i )
{
temp.a *= a;
temp.b *= b;
}
//temp.reduce();
return temp;
}

void Rational::swap()
{
int temp = a;
a = b;
b = temp;
}

void Rational::exchangeSign()
{
if ( a * b < 0 )
{
a = abs( a ); b = abs( b );
}
else
{
a = -a;
}
}

void toLog( std::fstream &f, std::string &msg, Rational &rat )
{
f << "=====================================================" << std::endl;
f << msg << " => " << rat << std::endl;
f << "=====================================================" << std::endl;
}

void printLogFile( std::fstream &f )
{
f.close();
f.open( "log.txt" );
std::string s;
while ( std::getline( f, s ) )
std::cout << s << std::endl;
std::cout << std::endl;
f.close();
}

void menu()
{
std::cout << std::endl;
std::cout << "1) Ввод двух дробей;" << std::endl;
std::cout << "2) Сумма;" << std::endl;
std::cout << "3) Разность;" << std::endl;
std::cout << "4) Произведение;" << std::endl;
std::cout << "5) Деление первой на вторую;" << std::endl;
std::cout << "6) Возведение двух дробей в степень;" << std::endl;
std::cout << "7) Обмен местами числителей и занменателей двух дробей;" << std::endl;
std::cout << "8) Смена знака у двух дробей;" << std::endl;
std::cout << "9) Просмотреть лог - файл;" << std::endl;
std::cout << "0) Выход;" << std::endl;
std::cout << std::endl;
}

int main()
{
setlocale( 0, "" );

std::fstream logFile( "log.txt", std::ios::app );

Rational first, second, third( 0, 0 );

int choice;

do
{
menu();
std::cout << "Ваш выбор : ";
std::cin >> choice;

switch ( choice )
{
case 1 : {
std::cout << "Введите первую дробь : "; std::cin >> first;
toLog( logFile, std::string( "Ввод первой дроби" ), first );
std::cout << "Введите вторую дробь : "; std::cin >> second;
toLog( logFile, std::string( "Ввод второй дроби" ), second );
} break;
case 2 : {
third = first + second;
std::cout << "Сумма : " << third << std::endl;
toLog( logFile, std::string( "Сумма двух дробей" ), third );
} break;
case 3 : {
third = first - second;
std::cout << "Разность : " << third << std::endl;
toLog( logFile, std::string( "Разность двух дробей" ), third );
} break;
case 5 : {
third = first / second;
std::cout << "Деление : " << third << std::endl;
toLog( logFile, std::string( "Деление первой дроби на вторую" ), third );
} break;
case 4 : {
third = first * second;
std::cout << "Произведение : " << third << std::endl;
toLog( logFile, std::string( "Произведение двух дробей" ), third );
} break;
case 6 : {
int deg;
std::cout << "Введите степень : ";
std::cin >> deg;
first = first ^ deg;
second = second ^ deg;

std::cout << "Возведение первой в степень : " << first << std::endl;
std::cout << "Возведение второй в степень : " << second << std::endl;
toLog( logFile, std::string( "Возведение в степень первой дроби" ), first );
toLog( logFile, std::string( "Возведение в степень второй дроби" ), second );
} break;
case 7 : {
first.swap();
second.swap();
std::cout << "Обмен местами числителя и знаменателя : " << first << " " << second << std::endl;
toLog( logFile, std::string( "Обмен первой дроби" ), first );
toLog( logFile, std::string( "Обмен второй дроби" ), second );
} break;
case 8 : {
first.exchangeSign();
second.exchangeSign();
std::cout << "Обмен знаков : " << first << " " << second << std::endl;
toLog( logFile, std::string( "Обмен у первой дроби" ), first );
toLog( logFile, std::string( "Обмен у второй дроби" ), second );
} break;
case 9 : {
printLogFile( logFile );
logFile.open( "log.txt", std::ios::app );
} break;
}
}
while ( choice != 0 );


return 0;
}
если у кого верно работает то скажите
 
R

rrrFer

#3
Код:
Rational& Rational::operator* ( Rational &r )
{
Rational temp; // это временный объект, который будет удален при возврате из функции
temp.a = a * r.a;
temp.b = b * r.b;
temp.reduce();
return temp; // нельзя возвращать временный объект
}
Ты можешь попробовать как-нибудь извратиться, например писать
static Rational temp;
или
убрать амперсанд:
Rational Rational::eek:perator* ( Rational &r )

первый вариант не очень красивый, но вцелом, адекватный. Второй - ужасен.

Ну а вцелом, при умножении двух чисел должно создаваться новое число - пиши что-то типа
Rational *temp = new Rational;
но тогда появляется опастность утечки, зато все логично.