diff --git a/runners/calculator/calculatorrunner.h b/runners/calculator/calculatorrunner.h --- a/runners/calculator/calculatorrunner.h +++ b/runners/calculator/calculatorrunner.h @@ -47,7 +47,7 @@ QMimeData * mimeDataForMatch(const Plasma::QueryMatch &match) override; private: - QString calculate(const QString& term); + QString calculate(const QString& term, bool *isApproximate); void userFriendlySubstitutions(QString& cmd); void powSubstitutions(QString& cmd); void hexSubstitutions(QString& cmd); diff --git a/runners/calculator/calculatorrunner.cpp b/runners/calculator/calculatorrunner.cpp --- a/runners/calculator/calculatorrunner.cpp +++ b/runners/calculator/calculatorrunner.cpp @@ -262,7 +262,8 @@ cmd.replace(QRegExp(QStringLiteral("([a-zA-Z]+)")), QStringLiteral("Math.\\1")); //needed for accessing math funktions like sin(),.... #endif - QString result = calculate(cmd); + bool isApproximate = false; + QString result = calculate(cmd, &isApproximate); if (!result.isEmpty() && result != cmd) { if (toHex) { result = "0x" + QString::number(result.toInt(), 16).toUpper(); @@ -272,19 +273,22 @@ match.setType(Plasma::QueryMatch::InformationalMatch); match.setIconName(QStringLiteral("accessories-calculator")); match.setText(result); + if (isApproximate) { + match.setSubtext(i18nc("The result of the calculation is only an approximation", "Approximation")); + } match.setData(result); match.setId(term); context.addMatch(match); } } -QString CalculatorRunner::calculate(const QString& term) +QString CalculatorRunner::calculate(const QString& term, bool *isApproximate) { #ifdef ENABLE_QALCULATE QString result; try { - result = m_engine->evaluate(term); + result = m_engine->evaluate(term, isApproximate); } catch(std::exception& e) { qDebug() << "qalculate error: " << e.what(); } diff --git a/runners/calculator/qalculate_engine.h b/runners/calculator/qalculate_engine.h --- a/runners/calculator/qalculate_engine.h +++ b/runners/calculator/qalculate_engine.h @@ -35,7 +35,7 @@ QString lastResult() const { return m_lastResult; } public Q_SLOTS: - QString evaluate(const QString& expression); + QString evaluate(const QString& expression, bool *isApproximate = nullptr); void updateExchangeRates(); void copyToClipboard(bool flag = true); diff --git a/runners/calculator/qalculate_engine.cpp b/runners/calculator/qalculate_engine.cpp --- a/runners/calculator/qalculate_engine.cpp +++ b/runners/calculator/qalculate_engine.cpp @@ -79,7 +79,7 @@ } } -QString QalculateEngine::evaluate(const QString& expression) +QString QalculateEngine::evaluate(const QString& expression, bool *isApproximate) { if (expression.isEmpty()) { return ""; @@ -98,6 +98,10 @@ eo.parse_options.angle_unit = ANGLE_UNIT_RADIANS; eo.structuring = STRUCTURING_SIMPLIFY; + // suggested in https://github.com/Qalculate/libqalculate/issues/16 + // to avoid memory overflow for seemingly innocent calculations (Bug 277011) + eo.approximation = APPROXIMATION_APPROXIMATE; + CALCULATOR->setPrecision(16); MathStructure result = CALCULATOR->calculate(ctext, eo); @@ -114,6 +118,10 @@ m_lastResult = result.print(po).c_str(); + if (isApproximate) { + *isApproximate = result.isApproximate(); + } + return m_lastResult; }