Operators

This commit is contained in:
Tobias Berger 2021-09-17 14:47:29 +02:00
parent 1b7b25e09e
commit 69874ba9f4
3 changed files with 223 additions and 35 deletions

View file

@ -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);
}
} }

View file

@ -1,7 +1,44 @@
#pragma once #pragma once
class Fraction #include <QString>
{
public: namespace FractionNS {
class Fraction
{
private:
int m_numerator, m_denominator;
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&);
};
}

View file

@ -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"