Skip to content

Commit

Permalink
Remove Real::toString(precision)
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Apr 8, 2024
1 parent ee66ed5 commit cd9d084
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 73 deletions.
2 changes: 0 additions & 2 deletions include/fintamath/numbers/Real.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ class Real : public INumberCRTP<Real> {

std::string toString() const noexcept override;

std::string toString(unsigned precision) const noexcept;

bool isPrecise() const noexcept override;

int sign() const noexcept;
Expand Down
33 changes: 14 additions & 19 deletions src/fintamath/numbers/Real.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <string>
#include <utility>

#include <fmt/format.h>

#include <boost/multiprecision/detail/default_ops.hpp>

#include "fintamath/exceptions/InvalidInputException.hpp"
Expand Down Expand Up @@ -75,23 +77,7 @@ Real::Real(const Integer &rhs)
isNegative(rhs < 0) {}

std::string Real::toString() const noexcept {
std::string res = toString(outputPrecision);

if (isNegative && res.front() != '-') {
res.insert(res.begin(), '-');
}

return res;
}

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

if (precision == 0) {
precision++;
}

std::string str = backend.str(static_cast<std::streamsize>(precision));
std::string str = backend.str(static_cast<std::streamsize>(outputPrecision));
size_t expPos = str.find('e');

if (expPos != std::string::npos) {
Expand Down Expand Up @@ -122,6 +108,10 @@ std::string Real::toString(unsigned precision) const noexcept {
str.erase(str.size() - 2, 2);
}

if (isNegative && str.front() != '-') {
str.insert(str.begin(), '-');
}

return str;
}

Expand Down Expand Up @@ -150,7 +140,13 @@ unsigned Real::getOutputPrecision() const {
}

void Real::setOutputPrecision(const unsigned precision) {
assert(precision <= outputPrecision);
if (precision > outputPrecision) {
throw InvalidInputException(fmt::format(
"The given precision {} is greater than the current precision {}",
precision,
outputPrecision));
}

outputPrecision = precision;
}

Expand Down Expand Up @@ -253,5 +249,4 @@ Real::ScopedSetPrecision::ScopedSetPrecision(const unsigned precision) {
Real::ScopedSetPrecision::~ScopedSetPrecision() {
setPrecision(currPrecision);
}

}
76 changes: 24 additions & 52 deletions tests/src/numbers/RealTests.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "fintamath/numbers/Real.hpp"
Expand Down Expand Up @@ -69,7 +70,7 @@ TEST(RealTests, rationalAssignmentOperatorConstructorTest) {
EXPECT_EQ((a = Rational(2, 4)).toString(), "0.5");

Real b;
EXPECT_EQ((b = Rational(1, 3)).toString(5), "0.33333");
EXPECT_EQ((b = Rational(1, 3)).toString(), "0.33333333333333333333");
}

TEST(RealTests, integerConstructorTest) {
Expand Down Expand Up @@ -368,7 +369,7 @@ TEST(RealTests, divideAssignmentOperatorTest) {
EXPECT_EQ((Real(10) /= Real(2)).toString(), "5.0");
EXPECT_EQ((Real("2.255") /= Real("-1.1")).toString(), "-2.05");
EXPECT_EQ((Real("-12.1") /= Real("1.1")).toString(), "-11.0");
EXPECT_EQ((Real("-11") /= Real("-3")).toString(5), "3.6667");
EXPECT_EQ((Real("-11") /= Real("-3")).toString(), "3.6666666666666666667");

EXPECT_EQ(Real("0") /= Real("-2"), Real("-0.0"));
EXPECT_EQ(Real("-0") /= Real("2"), Real("-0.0"));
Expand All @@ -384,15 +385,15 @@ TEST(RealTests, rationalDivideAssignmentOperatorTest) {
TEST(RealTests, integerDivideAssignmentOperatorTest) {
EXPECT_EQ((Real(10) /= Integer(2)).toString(), "5.0");
EXPECT_EQ((Real(10) /= Integer(-2)).toString(), "-5.0");
EXPECT_EQ((Real("22.5") /= Integer(-11)).toString(5), "-2.0455");
EXPECT_EQ((Real("22.5") /= Integer(-11)).toString(), "-2.0454545454545454545");
EXPECT_EQ((Real("-27.5") /= Integer(-11)).toString(), "2.5");
}

TEST(RealTests, intDivideAssignmentOperatorTest) {
EXPECT_EQ((Real("0.66") /= 3).toString(), "0.22");
EXPECT_EQ((Real("-73.85") /= 3).toString(5), "-24.617");
EXPECT_EQ((Real("73.8") /= -71).toString(5), "-1.0394");
EXPECT_EQ((Real("-73.8") /= -71).toString(5), "1.0394");
EXPECT_EQ((Real("-73.85") /= 3).toString(), "-24.616666666666666667");
EXPECT_EQ((Real("73.8") /= -71).toString(), "-1.0394366197183098592");
EXPECT_EQ((Real("-73.8") /= -71).toString(), "1.0394366197183098592");
}

TEST(RealTests, divideOperatorTest) {
Expand All @@ -410,15 +411,15 @@ TEST(RealTests, rationalDivideOperatorTest) {
TEST(RealTests, integerDivideOperatorTest) {
EXPECT_EQ((Real(10) / Integer(2)).toString(), "5.0");
EXPECT_EQ((Real(10) / Integer(-2)).toString(), "-5.0");
EXPECT_EQ((Real("22.5") / Integer(-11)).toString(5), "-2.0455");
EXPECT_EQ((Real("22.5") / Integer(-11)).toString(), "-2.0454545454545454545");
EXPECT_EQ((Real("-27.5") / Integer(-11)).toString(), "2.5");
}

TEST(RealTests, intDivideOperatorTest) {
EXPECT_EQ((Real("0.66") / 3).toString(), "0.22");
EXPECT_EQ((Real("-73.85") / 3).toString(5), "-24.617");
EXPECT_EQ((Real("73.8") / -71).toString(5), "-1.0394");
EXPECT_EQ((Real("-73.8") / -71).toString(5), "1.0394");
EXPECT_EQ((Real("-73.85") / 3).toString(), "-24.616666666666666667");
EXPECT_EQ((Real("73.8") / -71).toString(), "-1.0394366197183098592");
EXPECT_EQ((Real("-73.8") / -71).toString(), "1.0394366197183098592");
}

TEST(RealTests, rationalFriendDivideOperatorTest) {
Expand All @@ -435,10 +436,10 @@ TEST(RealTests, integerFriendDivideOperatorTest) {
}

TEST(RealTests, intFriendDivideOperatorTest) {
EXPECT_EQ((3 / Real("0.66")).toString(5), "4.5455");
EXPECT_EQ((3 / Real("-73.85")).toString(5), "-0.040623");
EXPECT_EQ((-71 / Real("73.8")).toString(5), "-0.96206");
EXPECT_EQ((-71 / Real("-73.8")).toString(5), "0.96206");
EXPECT_EQ((3 / Real("0.66")).toString(), "4.5454545454545454545");
EXPECT_EQ((3 / Real("-73.85")).toString(), "-0.040622884224779959377");
EXPECT_EQ((-71 / Real("73.8")).toString(), "-0.96205962059620596206");
EXPECT_EQ((-71 / Real("-73.8")).toString(), "0.96205962059620596206");
}

TEST(RealTests, unaryPlusOperatorTest) {
Expand Down Expand Up @@ -829,46 +830,11 @@ TEST(RealTests, toStringTest) {
EXPECT_EQ(Real("2.334455").toString(), "2.334455");
EXPECT_EQ(Real("11821937432984732987").toString(), "11821937432984732987.0");
EXPECT_EQ(Real("-1182193743298473298").toString(), "-1182193743298473298.0");
EXPECT_EQ(Real("0.000000001").toString(), "1.0*10^-9");
EXPECT_EQ(Real("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").toString(), "1.0*10^90");
EXPECT_EQ(Real("-1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").toString(), "-1.0*10^90");
}

TEST(RealTests, toStringPrecisionPrecisionTest) {
Real val = Rational(1, 3);
EXPECT_EQ(val.toString(1), "0.3");
EXPECT_EQ(val.toString(2), "0.33");
EXPECT_EQ(val.toString(3), "0.333");
EXPECT_EQ(val.toString(10), "0.3333333333");

val = -val;
EXPECT_EQ(val.toString(1), "-0.3");
EXPECT_EQ(val.toString(2), "-0.33");
EXPECT_EQ(val.toString(3), "-0.333");
EXPECT_EQ(val.toString(10), "-0.3333333333");

val = Real("100000000000000.37841620837012");
EXPECT_EQ(val.toString(18), "100000000000000.378");

val = Real("100000000000000.3775");
EXPECT_EQ(val.toString(18), "100000000000000.378");

val = Real("0.000000001");
EXPECT_EQ(val.toString(1), "1.0*10^-9");

val = Real("1000000000.1");
EXPECT_EQ(val.toString(1), "1.0*10^9");

val = Real("10.1");
EXPECT_EQ(val.toString(1), "1.0*10");

val = Real("10.1");
EXPECT_EQ(val.toString(0), "1.0*10");

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

TEST(RealTests, getOutputPrecisionTest) {
EXPECT_EQ(Real().getOutputPrecision(), Real::getPrecision());
}
Expand All @@ -886,8 +852,14 @@ TEST(RealTests, setOutputPrecisionTest) {
a.setOutputPrecision(5);
EXPECT_EQ(a.getOutputPrecision(), 5);

EXPECT_DEBUG_DEATH(a.setOutputPrecision(6), "");
EXPECT_DEBUG_DEATH(a.setOutputPrecision(10), "");
EXPECT_THAT(
[&] { a.setOutputPrecision(6); },
testing::ThrowsMessage<InvalidInputException>(
testing::StrEq("Invalid input: The given precision 6 is greater than the current precision 5")));
EXPECT_THAT(
[&] { a.setOutputPrecision(10); },
testing::ThrowsMessage<InvalidInputException>(
testing::StrEq("Invalid input: The given precision 10 is greater than the current precision 5")));
}

TEST(RealTests, updatePrecisionTest) {
Expand Down

0 comments on commit cd9d084

Please sign in to comment.