pow
This commit is contained in:
parent
85e1b0c77e
commit
87759391d8
3 changed files with 88 additions and 1 deletions
41
fraction.cpp
41
fraction.cpp
|
@ -1,7 +1,8 @@
|
||||||
#include "fraction.hpp"
|
#include "fraction.hpp"
|
||||||
|
|
||||||
namespace FractionNS {
|
#include <QtMath>
|
||||||
|
|
||||||
|
namespace FractionNS {
|
||||||
int gcd(int p, int q) {
|
int gcd(int p, int q) {
|
||||||
if(p < 0) p = -p;
|
if(p < 0) p = -p;
|
||||||
if(q < 0) q = -q;
|
if(q < 0) q = -q;
|
||||||
|
@ -270,6 +271,44 @@ namespace FractionNS {
|
||||||
return *this;
|
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 {
|
Fraction& Fraction::operator-() const {
|
||||||
return *new Fraction(-m_numerator, m_denominator);
|
return *new Fraction(-m_numerator, m_denominator);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,13 @@ namespace FractionNS {
|
||||||
Fraction& operator/=(const int);
|
Fraction& operator/=(const int);
|
||||||
Fraction& operator/=(const Fraction&);
|
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
|
// Unary operators
|
||||||
Fraction& operator-() const;
|
Fraction& operator-() const;
|
||||||
Fraction& operator+() const; // Should return a copy of the Fraction.
|
Fraction& operator+() const; // Should return a copy of the Fraction.
|
||||||
|
|
|
@ -29,6 +29,7 @@ private slots:
|
||||||
void test_less_than_or_equal();
|
void test_less_than_or_equal();
|
||||||
void test_greater_than_or_equal();
|
void test_greater_than_or_equal();
|
||||||
void test_inverse();
|
void test_inverse();
|
||||||
|
void test_pow();
|
||||||
};
|
};
|
||||||
|
|
||||||
FractionTest::FractionTest() {
|
FractionTest::FractionTest() {
|
||||||
|
@ -442,6 +443,46 @@ void FractionTest::test_inverse() {
|
||||||
QVERIFY(threw_divide_by_zero_error);
|
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)
|
QTEST_APPLESS_MAIN(FractionTest)
|
||||||
|
|
||||||
#include "tst_fractiontest.moc"
|
#include "tst_fractiontest.moc"
|
||||||
|
|
Reference in a new issue