diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 5dfb360fe..a00cdc3b0 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -198,7 +198,15 @@ std::string MathLib::add(const std::string & first, const std::string & second) if (MathLib::isInt(first) && MathLib::isInt(second)) { return toString(toLongNumber(first) + toLongNumber(second)); } - return toString(toDoubleNumber(first) + toDoubleNumber(second)); + + double d1 = toDoubleNumber(first); + double d2 = toDoubleNumber(second); + while (d1 > 100000.0 * d2 && toString(d1+d2)==first) + d2 *= 10.0; + while (d2 > 100000.0 * d1 && toString(d1+d2)==second) + d1 *= 10.0; + + return toString(d1 + d2); } std::string MathLib::subtract(const std::string &first, const std::string &second) @@ -206,7 +214,15 @@ std::string MathLib::subtract(const std::string &first, const std::string &secon if (MathLib::isInt(first) && MathLib::isInt(second)) { return toString(toLongNumber(first) - toLongNumber(second)); } - return toString(toDoubleNumber(first) - toDoubleNumber(second)); + + double d1 = toDoubleNumber(first); + double d2 = toDoubleNumber(second); + while (d1 > 100000.0 * d2 && toString(d1-d2)==first) + d2 *= 10.0; + while (d2 > 100000.0 * d1 && toString(d1-d2)==second) + d1 *= 10.0; + + return toString(d1 - d2); } std::string MathLib::divide(const std::string &first, const std::string &second) diff --git a/lib/mathlib.h b/lib/mathlib.h index 5a99bddf6..4c5a551c2 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -39,6 +39,7 @@ public: template static std::string toString(const T &d) { std::ostringstream result; + result.precision(8); result << d; if (isNullValue(result.str())) return std::string("0"); diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index 8519bdd56..b0ab04c57 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -87,6 +87,7 @@ private: ASSERT_EQUALS("-1" , MathLib::add("0", "-1")); ASSERT_EQUALS("1" , MathLib::add("1", "0")); ASSERT_EQUALS("0" , MathLib::add("0", "0.")); + ASSERT_EQUALS("1.0000001" , MathLib::add("1", "0.00000001")); // #4016 // subtraction ASSERT_EQUALS("254", MathLib::subtract("0xff", "1")); @@ -96,6 +97,7 @@ private: ASSERT_EQUALS("1" , MathLib::subtract("0", "-1")); ASSERT_EQUALS("1" , MathLib::subtract("1", "0")); ASSERT_EQUALS("0" , MathLib::subtract("0", "0.")); + ASSERT_EQUALS("0.99999999" , MathLib::subtract("1", "0.00000001")); // #4016 // multiply ASSERT_EQUALS("-0.003" , MathLib::multiply("-1e-3", "3"));