#include #include #include #include #include "layout/nth_root_layout.h" extern "C" { #include } #include namespace Poincare { NthRoot::NthRoot() : Function("root", 2) { } Expression::Type NthRoot::type() const { return Type::NthRoot; } Expression * NthRoot::cloneWithDifferentOperands(Expression** newOperands, int numberOfOperands, bool cloneOperands) const { assert(newOperands != nullptr); NthRoot * r = new NthRoot(); r->setArgument(newOperands, numberOfOperands, cloneOperands); return r; } ExpressionLayout * NthRoot::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const { assert(floatDisplayMode != FloatDisplayMode::Default); assert(complexFormat != ComplexFormat::Default); return new NthRootLayout(m_args[0]->createLayout(floatDisplayMode, complexFormat), m_args[1]->createLayout(floatDisplayMode, complexFormat)); } template Evaluation * NthRoot::templatedEvaluate(Context& context, AngleUnit angleUnit) const { Evaluation * base = m_args[0]->evaluate(context, angleUnit); Evaluation * index = m_args[1]->evaluate(context, angleUnit); Complex result = Complex::Float(NAN); if (base->numberOfOperands() == 1 || index->numberOfOperands() == 1) { result = compute(*(base->complexOperand(0)), *(index->complexOperand(0))); } delete base; delete index; return new Complex(result); } template Complex NthRoot::compute(const Complex c, const Complex d) const { if (c.a() >= 0 && c.b() == 0 && d.b() == 0) { return Complex::Float(std::pow(c.a(), 1/d.a())); } Complex invIndex = Fraction::compute(Complex::Float(1), d); return Power::compute(c, invIndex); } }