Operators
This commit is contained in:
parent
1b7b25e09e
commit
69874ba9f4
3 changed files with 223 additions and 35 deletions
95
fraction.cpp
95
fraction.cpp
|
@ -1,5 +1,96 @@
|
||||||
#include "fraction.hpp"
|
#include "fraction.hpp"
|
||||||
|
|
||||||
Fraction::Fraction()
|
namespace FractionNS {
|
||||||
{
|
|
||||||
|
int gcd(int p, int q) {
|
||||||
|
while(true) {
|
||||||
|
if(p == 0) return q;
|
||||||
|
q %= p;
|
||||||
|
if(q == 0) return p;
|
||||||
|
p %= q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcm(int p, int q) {
|
||||||
|
int gcd = FractionNS::gcd(p, q);
|
||||||
|
|
||||||
|
return gcd != 0 ? (p / gcd * q) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int abs(int n) {
|
||||||
|
if(n < 0) return -n;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Fraction::Fraction(int numerator, int denominator)
|
||||||
|
{
|
||||||
|
auto gcd = FractionNS::gcd(FractionNS::abs(numerator), FractionNS::abs(denominator));
|
||||||
|
|
||||||
|
if(denominator < 0) {
|
||||||
|
numerator *= -1;
|
||||||
|
denominator *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_numerator = numerator / gcd;
|
||||||
|
this->m_denominator = denominator / gcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Fraction::getNumerator() const { return m_numerator; }
|
||||||
|
int Fraction::getDenominator() const { return m_denominator; }
|
||||||
|
|
||||||
|
void Fraction::setNumerator(int numerator) {
|
||||||
|
auto gcd = std::__gcd(numerator, this->m_denominator);
|
||||||
|
this->m_numerator = numerator / gcd;
|
||||||
|
}
|
||||||
|
void Fraction::setDenominator(int denominator) {
|
||||||
|
auto gcd = std::__gcd(this->m_numerator, denominator);
|
||||||
|
this->m_denominator = denominator / gcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Fraction::display() const {
|
||||||
|
return QString::number(m_numerator) + '/' + QString::number(m_denominator);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Fraction::operator==(const int n) const {
|
||||||
|
return (double(m_numerator) / double(m_denominator)) == n;
|
||||||
|
}
|
||||||
|
bool Fraction::operator==(const float n) const {
|
||||||
|
return (double(m_numerator) / double(m_denominator)) == n;
|
||||||
|
}
|
||||||
|
bool Fraction::operator==(const double n) const {
|
||||||
|
return (double(m_numerator) / double(m_denominator)) == n;
|
||||||
|
}
|
||||||
|
bool Fraction::operator==(const Fraction& n) const {
|
||||||
|
return (this->m_numerator == n.getNumerator())
|
||||||
|
&& (this->m_denominator == n.getDenominator());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Fraction::operator!=(const int n) const {
|
||||||
|
return (double(m_numerator) / double(m_denominator)) != n;
|
||||||
|
}
|
||||||
|
bool Fraction::operator!=(const float n) const {
|
||||||
|
return (double(m_numerator) / double(m_denominator)) != n;
|
||||||
|
}
|
||||||
|
bool Fraction::operator!=(const double n) const {
|
||||||
|
return (double(m_numerator) / double(m_denominator)) != n;
|
||||||
|
}
|
||||||
|
bool Fraction::operator!=(const Fraction& n) const {
|
||||||
|
return (this->m_numerator != n.getNumerator())
|
||||||
|
|| (this->m_denominator != n.getDenominator());
|
||||||
|
}
|
||||||
|
|
||||||
|
Fraction& Fraction::operator+(const int n) const {
|
||||||
|
return Fraction(n) + *this;
|
||||||
|
}
|
||||||
|
Fraction& Fraction::operator+(const float n) const {
|
||||||
|
return Fraction(n) + *this;
|
||||||
|
}
|
||||||
|
Fraction& Fraction::operator+(const double n) const {
|
||||||
|
return Fraction(n) + *this;
|
||||||
|
}
|
||||||
|
Fraction& Fraction::operator+(const Fraction& other) const {
|
||||||
|
auto lcm = FractionNS::lcm(getDenominator(), other.getDenominator());
|
||||||
|
return *new Fraction((getNumerator() + other.getNumerator()) * lcm, getDenominator() * lcm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
37
fraction.hpp
37
fraction.hpp
|
@ -1,7 +1,44 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace FractionNS {
|
||||||
class Fraction
|
class Fraction
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
int m_numerator, m_denominator;
|
||||||
public:
|
public:
|
||||||
Fraction(int, int);
|
Fraction(int, int);
|
||||||
|
Fraction(int);
|
||||||
|
Fraction(double);
|
||||||
|
Fraction(float);
|
||||||
|
Fraction(const Fraction&);
|
||||||
|
|
||||||
|
int getNumerator() const;
|
||||||
|
int getDenominator() const;
|
||||||
|
void setNumerator(const int);
|
||||||
|
void setDenominator(const int);
|
||||||
|
|
||||||
|
QString display() const;
|
||||||
|
|
||||||
|
bool operator==(const int) const;
|
||||||
|
bool operator==(const float) const;
|
||||||
|
bool operator==(const double) const;
|
||||||
|
bool operator==(const Fraction&) const;
|
||||||
|
|
||||||
|
bool operator!=(const int) const;
|
||||||
|
bool operator!=(const float) const;
|
||||||
|
bool operator!=(const double) const;
|
||||||
|
bool operator!=(const Fraction&) const;
|
||||||
|
|
||||||
|
Fraction& operator+(const int) const;
|
||||||
|
Fraction& operator+(const float) const;
|
||||||
|
Fraction& operator+(const double) const;
|
||||||
|
Fraction& operator+(const Fraction&) const;
|
||||||
|
|
||||||
|
Fraction& operator+=(const int);
|
||||||
|
Fraction& operator+=(const float);
|
||||||
|
Fraction& operator+=(const double);
|
||||||
|
Fraction& operator+=(const Fraction&);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "fraction.hpp"
|
#include "fraction.hpp"
|
||||||
|
|
||||||
|
using namespace FractionNS;
|
||||||
|
|
||||||
class FractionTest : public QObject
|
class FractionTest : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -12,7 +14,10 @@ public:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void test_constructor();
|
void test_constructor();
|
||||||
|
void test_display();
|
||||||
void test_equivalence();
|
void test_equivalence();
|
||||||
|
void test_addition();
|
||||||
|
void test_inequivalence();
|
||||||
};
|
};
|
||||||
|
|
||||||
FractionTest::FractionTest()
|
FractionTest::FractionTest()
|
||||||
|
@ -27,40 +32,95 @@ FractionTest::~FractionTest()
|
||||||
|
|
||||||
void FractionTest::test_constructor()
|
void FractionTest::test_constructor()
|
||||||
{
|
{
|
||||||
|
// Normal fraction
|
||||||
Fraction f1 = Fraction(1, 2);
|
Fraction f1 = Fraction(1, 2);
|
||||||
QVERIFY(f1 == 0.5f);
|
QCOMPARE(f1.getNumerator(), 1);
|
||||||
QVERIFY(f1 == 0.5);
|
QCOMPARE(f1.getDenominator(), 2);
|
||||||
QVERIFY(f1.numerator() == 1);
|
|
||||||
QVERIFY(f1.denominator() == 2);
|
|
||||||
|
|
||||||
|
// Reducible fraction
|
||||||
Fraction f2 = Fraction(2,4);
|
Fraction f2 = Fraction(2,4);
|
||||||
QVERIFY(f1 == f2);
|
QCOMPARE(f2.getNumerator(), 1);
|
||||||
QVERIFY(f2 == 0.5f);
|
QCOMPARE(f2.getDenominator(), 2);
|
||||||
QVERIFY(f2 == 0.5);
|
|
||||||
QVERIFY(f2.numerator() == 1);
|
// Negative fractions
|
||||||
QVERIFY(f2.denominator() == 2);
|
Fraction f3 = Fraction(-1, 3);
|
||||||
|
QCOMPARE(f3.getNumerator(), -1);
|
||||||
|
QCOMPARE(f3.getDenominator(), 3);
|
||||||
|
|
||||||
|
Fraction f4 = Fraction(1, -3);
|
||||||
|
QCOMPARE(f4.getNumerator(), -1);
|
||||||
|
QCOMPARE(f4.getDenominator(), 3);
|
||||||
|
|
||||||
|
// Double negative (positive) fraction
|
||||||
|
Fraction f5 = Fraction(-2, -3);
|
||||||
|
QCOMPARE(f5.getNumerator(), 2);
|
||||||
|
QCOMPARE(f5.getDenominator(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FractionTest::test_display()
|
||||||
|
{
|
||||||
|
// Normal fraction
|
||||||
|
Fraction f1 = Fraction(1, 2);
|
||||||
|
QCOMPARE(f1.display(), "1/2");
|
||||||
|
Fraction f2 = Fraction(1, 3);
|
||||||
|
QCOMPARE(f2.display(), "1/3");
|
||||||
|
|
||||||
|
// Fractions that reduce
|
||||||
|
Fraction f3 = Fraction(2, 4);
|
||||||
|
QCOMPARE(f3.display(), "1/2");
|
||||||
|
Fraction f4 = Fraction(982929, 123456);
|
||||||
|
QCOMPARE(f4.display(), "327643/41152");
|
||||||
|
|
||||||
|
// Negative Fractions
|
||||||
|
Fraction f5 = Fraction(-5, 2);
|
||||||
|
QCOMPARE(f5.display(), "-5/2");
|
||||||
}
|
}
|
||||||
|
|
||||||
void FractionTest::test_equivalence()
|
void FractionTest::test_equivalence()
|
||||||
{
|
{
|
||||||
Fraction f1 = Fraction(1, 1);
|
Fraction f1 = Fraction(1, 1);
|
||||||
Fraction f2 = Fraction(1, 1);
|
Fraction f2 = Fraction(1, 1);
|
||||||
QVERIFY(f1 == f2);
|
Fraction f3 = Fraction(-1, 1);
|
||||||
|
|
||||||
QVERIFY(f1 == 1);
|
QCOMPARE(f1, f2);
|
||||||
QVERIFY(f1 == 1.0);
|
|
||||||
QVERIFY(f1 == 1.0f);
|
|
||||||
|
|
||||||
QVERIFY(f2 == 1);
|
QCOMPARE(f1, 1);
|
||||||
QVERIFY(f2 == 1.0);
|
QCOMPARE(f1, 1.0);
|
||||||
QVERIFY(f2 == 1.0f);
|
QCOMPARE(f1, 1.0f);
|
||||||
|
|
||||||
|
QCOMPARE(f2, 1);
|
||||||
|
QCOMPARE(f2, 1.0);
|
||||||
|
QCOMPARE(f2, 1.0f);
|
||||||
|
|
||||||
|
QCOMPARE(f3, -1);
|
||||||
|
QCOMPARE(f3, -1.0);
|
||||||
|
QCOMPARE(f3, -1.0f);
|
||||||
|
}
|
||||||
|
void FractionTest::test_inequivalence() {
|
||||||
|
Fraction f1 = Fraction(1, 1);
|
||||||
|
Fraction f2 = Fraction(-1, 1);
|
||||||
Fraction f3 = Fraction(2, 3);
|
Fraction f3 = Fraction(2, 3);
|
||||||
|
QVERIFY(f1 != f2);
|
||||||
|
QVERIFY(f2 != f3);
|
||||||
|
QVERIFY(f3 != f1);
|
||||||
|
|
||||||
QVERIFY(f3 != 1);
|
QVERIFY(f3 != 1);
|
||||||
QVERIFY(f3 != 1.0);
|
QVERIFY(f3 != 1.0);
|
||||||
QVERIFY(f3 != 1.0f);
|
QVERIFY(f3 != 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FractionTest::test_addition()
|
||||||
|
{
|
||||||
|
Fraction f1 = Fraction(1, 2);
|
||||||
|
QCOMPARE(f1 + 1.0f, 1.5f);
|
||||||
|
f1 += 1.0f;
|
||||||
|
QCOMPARE(f1, 1.5);
|
||||||
|
|
||||||
|
Fraction f2 = Fraction(1, 2);
|
||||||
|
QCOMPARE(f2 + 1.0f, 1.5f);
|
||||||
|
QCOMPARE(f2, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(FractionTest)
|
QTEST_APPLESS_MAIN(FractionTest)
|
||||||
|
|
||||||
#include "tst_fractiontest.moc"
|
#include "tst_fractiontest.moc"
|
||||||
|
|
Reference in a new issue