From ced136f8432be73612ef544898d462b54a233147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 14 Dec 2018 12:14:17 +0100 Subject: [PATCH] [poincare] Fix ComplexCartesian::powerInteger to handle pure imaginary complex --- poincare/src/complex_cartesian.cpp | 20 ++++++++++++++++++++ poincare/src/power.cpp | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/poincare/src/complex_cartesian.cpp b/poincare/src/complex_cartesian.cpp index 44d826e20..3446484cf 100644 --- a/poincare/src/complex_cartesian.cpp +++ b/poincare/src/complex_cartesian.cpp @@ -177,6 +177,26 @@ ComplexCartesian ComplexCartesian::powerInteger(int n, Context & context, Prefer Expression a = real(); Expression b = imag(); assert(n > 0); + assert(!b.isRationalZero()); + + // Special case: a == 0 (otherwise, we are going to introduce undefined expressions - a^0 = NAN) + // (b*i)^n = b^n*i^n with i^n == i, -i, 1 or -1 + if (a.isRationalZero()) { + ComplexCartesian result; + Expression bpow = Power(b, Rational(n)); + if (n/2%2 == 1) { + Expression temp = Multiplication(Rational(-1), bpow); + bpow.shallowReduce(context, angleUnit, target); + bpow = temp; + } + if (n%2 == 0) { + result = ComplexCartesian(bpow, Rational(0)); + } else { + result = ComplexCartesian(Rational(0), bpow); + } + bpow.shallowReduce(context, angleUnit, target); + return result; + } // (a+ib) = a^n+i*b*a^(n-1)+(-1)*b^2*a^(n-2)+(-i)*b^3*a^(n-3)+b^3*a^(n-4)+... // Real part: A = a^n+(-1)*b^2*a^(n-2)+... // Imaginary part: B = b*a^(n-1) diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 2b65816db..cfd0076c0 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -384,7 +384,7 @@ Expression Power::shallowReduce(Context & context, Preferences::AngleUnit angleU Expression base = childAtIndex(0); Expression index = childAtIndex(1); /* Step 0: if both children are true unresolved complexes, the result is not simplified. TODO? */ - if (!base.isReal(context, angleUnit) && !index.isReal(context, angleUnit)) { + if (!base.isReal(context, angleUnit) && base.type() != ExpressionNode::Type::ComplexCartesian && !index.isReal(context, angleUnit) && index.type() != ExpressionNode::Type::ComplexCartesian) { return *this; }