This commit is contained in:
Tobias Berger 2021-09-21 11:42:53 +02:00
parent 85e1b0c77e
commit 87759391d8
3 changed files with 88 additions and 1 deletions

View file

@ -1,7 +1,8 @@
#include "fraction.hpp"
namespace FractionNS {
#include <QtMath>
namespace FractionNS {
int gcd(int p, int q) {
if(p < 0) p = -p;
if(q < 0) q = -q;
@ -270,6 +271,44 @@ namespace FractionNS {
return *this;
}
double Fraction::pow(const int n) const {
if(n == 0) {
if(m_numerator == 0) {
throw not_defined_error();
}
return 1.0;
}
if(n < 0) {
if(m_numerator == 0) {
throw not_real_error();
}
if(n == -1) {
return double(m_denominator) / m_numerator;
}
return qPow(double(m_denominator) / m_numerator, -n);
}
return qPow(double(m_numerator) / m_denominator, n);
}
double Fraction::pow(const Fraction& other) const {
if(other == 0) {
if(m_numerator == 0) {
throw not_defined_error();
}
return 1.0;
}
if(other < 0) {
if(m_numerator == 0) {
throw not_real_error();
}
if(other == -1) {
return double(m_denominator) / m_numerator;
}
return qPow(double(m_denominator) / m_numerator, -other.toDouble());
}
return qPow(double(m_numerator) / m_denominator, other.toDouble());
}
Fraction& Fraction::operator-() const {
return *new Fraction(-m_numerator, m_denominator);
}

View file

@ -86,6 +86,13 @@ namespace FractionNS {
Fraction& operator/=(const int);
Fraction& operator/=(const Fraction&);
// Maybe replace with ^ operator, as it's unused for this class.
// Might be syntactically not-so-nice though?
// Python uses / for combining paths, does cpp do something similar anywhere?
// How does one raise a Fraction to a power while keeping it a Fraction (avoid double return type)
double pow(const int) const;
double pow(const Fraction&) const;
// Unary operators
Fraction& operator-() const;
Fraction& operator+() const; // Should return a copy of the Fraction.

View file

@ -29,6 +29,7 @@ private slots:
void test_less_than_or_equal();
void test_greater_than_or_equal();
void test_inverse();
void test_pow();
};
FractionTest::FractionTest() {
@ -442,6 +443,46 @@ void FractionTest::test_inverse() {
QVERIFY(threw_divide_by_zero_error);
}
void FractionTest::test_pow() {
const Fraction f1 = Fraction(2, 3);
const Fraction f2 = Fraction(3, 2);
const Fraction f3 = Fraction(4, 9);
const Fraction f4 = Fraction(9, 4);
QCOMPARE(f3, f1.pow(2));
QCOMPARE(f4, f2.pow(2));
const Fraction f5 = Fraction(9);
const Fraction f6 = Fraction(1, 9);
const Fraction f7 = Fraction(1, 81);
// x ** -y = (1 / x) ** y
QCOMPARE(f6, f5.pow(-1));
QCOMPARE(f7, f5.pow(-2));
const Fraction f8 = Fraction(16);
// x ** (1/y) = root_y(x)
QCOMPARE(f8.pow(Fraction(1, 2)), 4.0);
// x ** 0 = 1; (where x != 0 and x ∈ R)
// 0 ** 0 depends on context
QCOMPARE(f1.pow(0), 1.0);
bool threw_correct_error = false;
try {
Fraction(0, 2).pow(0);
} catch (const not_defined_error&) {
threw_correct_error = true;
}
QVERIFY(threw_correct_error);
threw_correct_error = false;
try {
Fraction(0, 1).pow(-1);
} catch (const not_real_error&) {
threw_correct_error = true;
}
QVERIFY(threw_correct_error);
}
QTEST_APPLESS_MAIN(FractionTest)
#include "tst_fractiontest.moc"