Skip to content

Commit

Permalink
Refactor numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Apr 8, 2024
1 parent 5d60414 commit 1367d92
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 75 deletions.
16 changes: 9 additions & 7 deletions include/fintamath/numbers/Complex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,21 @@ class Complex : public INumberCRTP<Complex> {

Complex &operator=(Complex &&rhs) noexcept = default;

explicit Complex(const std::string &str);

explicit Complex(const INumber &inReal, const INumber &inImag);

explicit Complex(int64_t inReal, int64_t inImag);

Complex(const Integer &rhs);

Complex(const Rational &rhs);

Complex(const Real &rhs);

Complex(int64_t rhs);
Complex(std::integral auto rhs) : re(std::make_unique<Integer>(rhs)) {}

explicit Complex(std::integral auto inReal, std::integral auto inImag)
: re(std::make_unique<Integer>(inReal)),
im(std::make_unique<Integer>(inImag)) {}

explicit Complex(const INumber &inReal, const INumber &inImag);

explicit Complex(const std::string &str);

std::string toString() const override;

Expand Down
7 changes: 2 additions & 5 deletions include/fintamath/numbers/Integer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,12 @@ class Integer : public INumberCRTP<Integer> {
public:
Integer() = default;

Integer(std::integral auto rhs) : backend(rhs) {}

Integer(Backend inBackend);

explicit Integer(std::string str);

explicit Integer(std::integral auto val) : backend(val) {
}

Integer(int64_t val);

std::string toString() const override;

int sign() const;
Expand Down
10 changes: 6 additions & 4 deletions include/fintamath/numbers/Rational.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ class Rational : public INumberCRTP<Rational> {
public:
Rational() = default;

explicit Rational(const std::string &str);

explicit Rational(Integer inNumer, Integer inDenom);
Rational(std::integral auto rhs) : numer(rhs) {}

Rational(Integer rhs);

Rational(int64_t rhs);
explicit Rational(Integer inNumer, Integer inDenom);

explicit Rational(const std::string &str);

std::string toString() const override;

Expand Down Expand Up @@ -62,7 +62,9 @@ class Rational : public INumberCRTP<Rational> {

static void toCommonDenominators(Rational &lhs, Rational &rhs);

private:
Integer numer = 0;

Integer denom = 1;
};

Expand Down
12 changes: 6 additions & 6 deletions include/fintamath/numbers/Real.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ class Real : public INumberCRTP<Real> {

Real(Backend inBackend);

explicit Real(std::string str);
Real(std::integral auto rhs)
: backend(rhs),
isNegative(rhs < 0) {}

Real(const Rational &val);
Real(const Rational &rhs);

Real(const Integer &val);
Real(const Integer &rhs);

Real(int64_t val);
explicit Real(std::string str);

std::string toString() const override;

Expand Down Expand Up @@ -99,8 +101,6 @@ class Real : public INumberCRTP<Real> {

void updatePrecision(const Real &rhs);

void validateNewPrecision(unsigned precision) const;

private:
Backend backend;

Expand Down
21 changes: 7 additions & 14 deletions src/fintamath/numbers/Complex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,6 @@ Complex::Complex(const std::string &str) {
}
}

Complex::Complex(const INumber &inReal, const INumber &inImag) {
if (is<Complex>(inReal) || is<Complex>(inImag)) {
throw InvalidInputException("Nested complex numbers are not allowed");
}

re = cast<INumber>(inReal.toMinimalObject());
im = cast<INumber>(inImag.toMinimalObject());
}

Complex::Complex(int64_t inReal, int64_t inImag) : re(std::make_unique<Integer>(inReal)),
im(std::make_unique<Integer>(inImag)) {
}

Complex::Complex(const Integer &rhs) : re(cast<INumber>(rhs.toMinimalObject())) {
}

Expand All @@ -66,7 +53,13 @@ Complex::Complex(const Rational &rhs) : re(cast<INumber>(rhs.toMinimalObject()))
Complex::Complex(const Real &rhs) : re(cast<INumber>(rhs.toMinimalObject())) {
}

Complex::Complex(int64_t rhs) : re(std::make_unique<Integer>(rhs)) {
Complex::Complex(const INumber &inReal, const INumber &inImag) {
if (is<Complex>(inReal) || is<Complex>(inImag)) {
throw InvalidInputException("Nested complex numbers are not allowed");
}

re = cast<INumber>(inReal.toMinimalObject());
im = cast<INumber>(inImag.toMinimalObject());
}

std::string Complex::toString() const {
Expand Down
3 changes: 0 additions & 3 deletions src/fintamath/numbers/Integer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ Integer::Integer(std::string str) {
}
}

Integer::Integer(const int64_t val) : backend(val) {
}

std::string Integer::toString() const {
return backend.str();
}
Expand Down
23 changes: 10 additions & 13 deletions src/fintamath/numbers/Rational.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ namespace fintamath {

FINTAMATH_CLASS_IMPLEMENTATION(Rational)

Rational::Rational(Integer rhs) : numer(std::move(rhs)) {
}

Rational::Rational(Integer inNumer, Integer inDenom)
: numer(std::move(inNumer)),
denom(std::move(inDenom)) {

toIrreducibleRational();
}

Rational::Rational(const std::string &str) {
if (str.empty()) {
throw InvalidInputException(str);
Expand Down Expand Up @@ -66,19 +76,6 @@ Rational::Rational(const std::string &str) {
}
}

Rational::Rational(Integer inNumer, Integer inDenom)
: numer(std::move(inNumer)),
denom(std::move(inDenom)) {

toIrreducibleRational();
}

Rational::Rational(Integer rhs) : numer(std::move(rhs)) {
}

Rational::Rational(const int64_t rhs) : numer(rhs) {
}

const Integer &Rational::numerator() const {
return numer;
}
Expand Down
28 changes: 8 additions & 20 deletions src/fintamath/numbers/Real.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "fintamath/numbers/Real.hpp"

#include <algorithm>
#include <cassert>
#include <compare>
#include <cstddef>
#include <cstdint>
Expand Down Expand Up @@ -66,17 +67,12 @@ Real::Real(std::string str) : Real() {
}
}

Real::Real(const Rational &val) {
*this = Real(val.numerator()) / Real(val.denominator());
}

Real::Real(const Integer &val) : backend(val.getBackend()),
isNegative(val < 0) {
}
Real::Real(const Rational &rhs)
: Real(Real(rhs.numerator()) / Real(rhs.denominator())) {}

Real::Real(const int64_t val) : backend(val),
isNegative(val < 0) {
}
Real::Real(const Integer &rhs)
: backend(rhs.getBackend()),
isNegative(rhs < 0) {}

std::string Real::toString() const {
std::string res = toString(outputPrecision);
Expand All @@ -89,7 +85,7 @@ std::string Real::toString() const {
}

std::string Real::toString(unsigned precision) const {
validateNewPrecision(precision);
assert(precision <= outputPrecision);

if (precision == 0) {
precision++;
Expand Down Expand Up @@ -154,7 +150,7 @@ unsigned Real::getOutputPrecision() const {
}

void Real::setOutputPrecision(const unsigned precision) {
validateNewPrecision(precision);
assert(precision <= outputPrecision);
outputPrecision = precision;
}

Expand Down Expand Up @@ -250,14 +246,6 @@ void Real::updatePrecision(const Real &rhs) {
outputPrecision = std::min(outputPrecision, rhs.outputPrecision);
}

void Real::validateNewPrecision(const unsigned precision) const {
if (precision > outputPrecision) {
// TODO: use std::format
throw InvalidInputException("Precision must be less than or equal to " +
std::to_string(outputPrecision));
}
}

Real::ScopedSetPrecision::ScopedSetPrecision(const unsigned precision) {
setPrecision(precision);
}
Expand Down
6 changes: 3 additions & 3 deletions tests/src/numbers/RealTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,7 @@ TEST(RealTests, toStringPrecisionPrecisionTest) {

Real::ScopedSetPrecision setPrecision(10);
val = Real("1.3");
EXPECT_THROW(val.toString(20), InvalidInputException);
EXPECT_DEBUG_DEATH(val.toString(20), "");
}

TEST(RealTests, getOutputPrecisionTest) {
Expand All @@ -886,8 +886,8 @@ TEST(RealTests, setOutputPrecisionTest) {
a.setOutputPrecision(5);
EXPECT_EQ(a.getOutputPrecision(), 5);

EXPECT_THROW(a.setOutputPrecision(6), InvalidInputException);
EXPECT_THROW(a.setOutputPrecision(10), InvalidInputException);
EXPECT_DEBUG_DEATH(a.setOutputPrecision(6), "");
EXPECT_DEBUG_DEATH(a.setOutputPrecision(10), "");
}

TEST(RealTests, updatePrecisionTest) {
Expand Down

0 comments on commit 1367d92

Please sign in to comment.