diff --git a/poincare/include/poincare/absolute_value.h b/poincare/include/poincare/absolute_value.h index 8f82ec507..408995c01 100644 --- a/poincare/include/poincare/absolute_value.h +++ b/poincare/include/poincare/absolute_value.h @@ -11,6 +11,7 @@ class AbsoluteValue : public StaticHierarchy<1> { public: Type type() const override; Expression * clone() const override; + bool isPositive() const override { return true; } private: template static Complex computeOnComplex(const Complex c, AngleUnit angleUnit); virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index f869e9d83..fead13c98 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -95,6 +95,9 @@ public: static Expression * parse(char const * string); virtual ~Expression() = default; virtual Expression * clone() const = 0; + /* If isPositive is false, the expression has no sign (it does have to be + * negative) */ + virtual bool isPositive() const { return false; } /* Poor man's RTTI */ virtual Type type() const = 0; diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index cd208f822..84a1137f9 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -13,6 +13,7 @@ class Power : public StaticHierarchy<2> { public: Type type() const override; Expression * clone() const override; + bool isPositive() const override; template static Complex compute(const Complex c, const Complex d); private: constexpr static float k_maxNumberOfSteps = 10000.0f; diff --git a/poincare/include/poincare/rational.h b/poincare/include/poincare/rational.h index 9b170692c..636754a68 100644 --- a/poincare/include/poincare/rational.h +++ b/poincare/include/poincare/rational.h @@ -24,6 +24,7 @@ public: // Expression subclassing Type type() const override; Expression * clone() const override; + bool isPositive() const override { return !isNegative(); } // Basic test bool isZero() const { return m_numerator.isZero(); } diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 6ee0b8b35..f712ce132 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -23,6 +23,16 @@ Expression * Power::clone() const { return new Power(m_operands, true); } +bool Power::isPositive() const { + if (operand(1)->type() == Type::Rational) { + const Rational * r = static_cast(operand(1)); + if (r->denominator().isOne() && Integer::Division(r->numerator(), Integer(2)).remainder.isZero()) { + return true; + } + } + return false; +} + template Complex Power::compute(const Complex c, const Complex d) { if (d.b() != 0) {