Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

rational.cpp (шаг 3)

Rational.cpp (шаг 1)

#include <iostream>

 

using namespace std;

 

class Rational

{

public:

Rational(const int num, const int den)

: num_{num}

, den_{den}

{

}

 

int num() const

{

return num_;

}

 

int den() const

{

return den_;

}

 

private:

int num_; ///< числитель

int den_; ///< знаменатель

};

 

int main()

{

Rational r{1, 2};

cout << "Rational{1, 2} -> num=" << r.num() << " den=" << r.den() << endl;

}

 

Результат работы


Увеличим количество тестов.

Rational.cpp (шаг 2)

#include <iostream>

 

using namespace std;

 

class Rational

{

public:

Rational(const int num, const int den)

: num_{num}

, den_{den}

{

}

 

int num() const

{

return num_;

}

 

int den() const

{

return den_;

}

 

private:

int num_; ///< числитель, целое

int den_; ///< знаменатель, натуральное

};

 

int main()

{

Rational r01{1, 2};

cout << "Rational{1, 2} -> num=" << r01.num() << " den=" << r01.den() << endl;

Rational r02{-1, 2};

cout << "Rational{-1, 2} -> num=" << r02.num() << " den=" << r02.den() << endl;

Rational r03{1, -2};

cout << "Rational{-1, 2} -> num=" << r03.num() << " den=" << r03.den() << endl;

Rational r04{-1, -2};

cout << "Rational{-1, -2} -> num=" << r04.num() << " den=" << r04.den() << endl;

}

 

Результат работы


Добавим функции нормализации и тестирования конструктора.

rational.cpp (шаг 3)

#include <iostream>

 

using namespace std;

 

class Rational

{

public:

Rational(const int num, const int den)

: num_{num}

, den_{den}

{

normalize();

}

 

int num() const

{

return num_;

}

 

int den() const

{

return den_;

}

 

private:

void normalize()

{

if (0 == num_)

{

den_ = 1;

}

else if (den_ < 0)

{

num_ *= -1;

den_ *= -1;

}

}

 

private:

int num_; ///< числитель, целое

int den_; ///< знаменатель, натуральное

};

 

void testRationalConstructor(const int num, const int den)

{

Rational r{num, den};

cout << "Rational{" << num << ", " << den << "} -> num=" << r.num()

<< " den=" << r.den() << endl;

}

 

int main()

{

testRationalConstructor(1, 2);

testRationalConstructor(-1, 2);

testRationalConstructor(1, -2);

testRationalConstructor(-1, -2);

 

cout << "\nSpecial cases" << endl;

testRationalConstructor(3, 6);

testRationalConstructor(-1, 0);

}

Результат работы


Много-много шагов спустя…

Rational.cpp

#include <iostream>

#include <stdexcept>

#include <sstream>

 

using namespace std;

 

class Rational

{

public:

Rational() noexcept

: Rational{0, 1}

{

}

 

Rational(const int num) noexcept

: Rational{num, 1}

{

}

 

Rational(const int num, const int den)

: num_{num}

, den_{den}

{

if (0 == den_)

{

throw domain_error("zero denominator in Rational");

}

normalize();

}

 

Rational(const Rational& rhs) noexcept = default;

 

Rational& operator=(const Rational& rhs) = default;

 

Rational& operator=(Rational&& rhs) = default;

 

int num() const

{

return num_;

}

 

int den() const

{

return den_;

}

 

Rational operator-() const

{

return Rational{-num_, den_};

}

 

Rational& operator+=(const Rational& rhs)

{

num_ = num_ * rhs.den_ + den_ * rhs.num_;

den_ *= rhs.den_;

normalize();

return *this;

}

 

Rational& operator-=(const Rational& rhs)

{

num_ = num_ * rhs.den_ - den_ * rhs.num_;

den_ *= rhs.den_;

normalize();

return *this;

}

 

Rational& operator*=(const Rational& rhs)

{

num_ *= rhs.num_;

den_ *= rhs.den_;

normalize();

return *this;

}

 

Rational& operator/=(const Rational& rhs)

{

num_ *= rhs.den_;

den_ *= rhs.num_;

normalize();

return *this;

}

 

bool operator==(const Rational& rhs) const

{

return (num_ == rhs.num_) && (den_ == rhs.den_);

}

 

bool operator!=(const Rational& rhs) const

{

return!operator==(rhs);

}

 

bool operator<(const Rational& rhs) const

{

return (num_ * rhs.den_) < (rhs.num_ * den_);

}

 

bool operator<=(const Rational& rhs) const

{

return (num_ * rhs.den_) <= (rhs.num_ * den_);

}

 

bool operator>(const Rational& rhs) const

{

return!operator<=(rhs);

}

 

bool operator>=(const Rational& rhs) const

{

return!operator<(rhs);;

}

 

 

ostream& writeToTxt(std::ostream& ostrm) const

{

ostrm << num_ << '/' << den_;

return ostrm;

}

 

istream& readFromTxt(std::istream& istrm)

{

int num{0};

istrm >> num;

char sep{0};

istrm >> sep;

if ('/'!= sep)

istrm.setstate(ios_base::failbit);

int den{0};

istrm >> den;

if (istrm)

{

num_ = num;

den_ = den;

normalize();

}

return istrm;

}

 

private:

void normalize()

{

if (0 == num_)

{

den_ = 1;

}

else if (den_ < 0)

{

num_ *= -1;

den_ *= -1;

// TODO: упрощение до несократимой дроби

}

}

 

private:

int num_; ///< числитель, целое

int den_; ///< знаменатель, натуральное

};

 

Rational operator+(const Rational& lhs, const Rational& rhs)

{

Rational summ{lhs};

summ += rhs;

return summ;

}

 

Rational operator-(const Rational& lhs, const Rational& rhs)

{

Rational summ{lhs};

summ -= rhs;

return summ;

}

 

Rational operator*(const Rational& lhs, const Rational& rhs)

{

Rational summ{lhs};

summ *= rhs;

return summ;

}

 

Rational operator/(const Rational& lhs, const Rational& rhs)

{

Rational summ{lhs};

summ /= rhs;

return summ;

}

 

std::ostream& operator<<(std::ostream& ostrm, const Rational& r)

{

return r.writeToTxt(ostrm);

}

 

std::istream& operator>>(std::istream& istrm, Rational& r)

{

return r.readFromTxt(istrm);

}

 

 

void testRationalConstructor(const int num, const int den)

{

cout << "Rational{" << num << ',' << den << "} -> " << flush;

cout << Rational{num, den} << endl;

}

 

void testRationalOpPlus(const Rational& lhs, const Rational& rhs)

{

cout << lhs << " + " << rhs << " -> " << (lhs + rhs) << endl;

}

 

void testRationalOpMinus(const Rational& lhs, const Rational& rhs)

{

cout << lhs << " - " << rhs << " -> " << (lhs - rhs) << endl;

}

 

void testRationalOpMult(const Rational& lhs, const Rational& rhs)

{

cout << lhs << " * " << rhs << " -> " << (lhs * rhs) << endl;

}

 

void testRationalOpDiv(const Rational& lhs, const Rational& rhs)

{

cout << lhs << " / " << rhs << " -> " << (lhs / rhs) << endl;

}

 

void testRationalOpCmpEq(const Rational& lhs, const Rational& rhs)

{

cout << lhs << " == " << rhs << " -> " << boolalpha << (lhs == rhs) << endl;

}

 

void testRationalOpCmpNotEq(const Rational& lhs, const Rational& rhs)

{

cout << lhs << "!= " << rhs << " -> " << boolalpha << (lhs!= rhs) << endl;

}

 

void testRationalOpCmpLess(const Rational& lhs, const Rational& rhs)

{

cout << lhs << " < " << rhs << " -> " << boolalpha << (lhs < rhs) << endl;

}

 

// TODO: test for operator<= operator> operator>=

 

void testReadFromStream(const string& s)

{

istringstream istrm(s);

Rational r;

istrm >> r;

cout << "Read from text \"" << s << "\" -> " << r << ", stream state is "

<< boolalpha <<!!istrm << endl;

}

 

int main()

{

cout << "Rational{} -> " << Rational{} << endl;

Rational r02{2};

cout << "Rational{} -> " << r02 << endl;

testRationalConstructor(1, 2);

testRationalConstructor(-1, 2);

testRationalConstructor(1, -2);

testRationalConstructor(-1, -2);

try

{

testRationalConstructor(5, 0);

}

catch (domain_error& e)

{

cout << "exception caught (" << e.what() << ')' << endl;

}

Rational r03{-1, 5};

Rational r04{2, -3};

 

cout << "\nTest Rational operator+" << endl;

testRationalOpPlus(r03, -r03);

testRationalOpPlus(r03, r04);

 

cout << "\nTest Rational operator-" << endl;

testRationalOpMinus(r03, r03);

testRationalOpMinus(r03, r04);

 

cout << "\nTest Rational operator*" << endl;

testRationalOpMult(r03, r03);

testRationalOpMult(r03, r04);

 

cout << "\nTest Rational operator/" << endl;

testRationalOpDiv(r03, r03);

testRationalOpDiv(r03, r04);

 

cout << "\nTest Rational operator==" << endl;

testRationalOpCmpEq(r03, r03);

testRationalOpCmpEq(r03, -r03);

testRationalOpCmpEq(r03, r04);

 

cout << "\nTest Rational operator!=" << endl;

testRationalOpCmpNotEq(r03, r03);

testRationalOpCmpNotEq(r03, -r03);

testRationalOpCmpNotEq(r03, r04);

 

cout << "\nTest Rational operator<" << endl;

testRationalOpCmpLess(r03, r03);

testRationalOpCmpLess(r03, -r03);

testRationalOpCmpLess(r03, r04);

 

// TODO: test for operator<= operator> operator>=

 

cout << "\nTest Rational read from stream" << endl;

testReadFromStream("");

testReadFromStream("1");

testReadFromStream("1/2");

testReadFromStream("-4/5");

testReadFromStream("3/-5");

testReadFromStream("-5/-2");

testReadFromStream("-5.0/-2");

}

Результат работы


Дата добавления: 2015-10-24; просмотров: 95 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Quality Rate (норма качества)| Заключительные мысли

mybiblioteka.su - 2015-2024 год. (0.036 сек.)