Numworks Epsilon  1.4.1
Graphing Calculator Operating System
factor.cpp
Go to the documentation of this file.
1 #include <poincare/factor.h>
2 #include <poincare/undefined.h>
3 #include <poincare/arithmetic.h>
4 #include <poincare/power.h>
5 #include <poincare/division.h>
6 #include <poincare/opposite.h>
7 
8 extern "C" {
9 #include <stdlib.h>
10 #include <assert.h>
11 }
12 #include <cmath>
13 
14 namespace Poincare {
15 
17  return Type::Factor;
18 }
19 
21  Factor * b = new Factor(m_operands, true);
22  return b;
23 }
24 
25 Expression * Factor::shallowBeautify(Context& context, AngleUnit angleUnit) {
26  Expression * op = editableOperand(0);
27  if (op->type() != Type::Rational) {
28  return new Undefined();
29  }
30  Rational * r = static_cast<Rational *>(op);
31  if (r->isZero()) {
32  return replaceWith(r, true);
33  }
34  Expression * numeratorDecomp = createMultiplicationOfIntegerPrimeDecomposition(r->numerator(), context, angleUnit);
35  Expression * result = numeratorDecomp;
36  if (result->type() == Type::Undefined) {
37  return replaceWith(result, true);
38  }
39  assert(numeratorDecomp->type() == Type::Multiplication);
40  if (!r->denominator().isOne()) {
41  Expression * denominatorDecomp = createMultiplicationOfIntegerPrimeDecomposition(r->denominator(), context, angleUnit);
42  if (denominatorDecomp->type() == Type::Undefined) {
43  delete result;
44  return replaceWith(denominatorDecomp, true);
45  }
46  assert(denominatorDecomp->type() == Type::Multiplication);
47  result = new Division(numeratorDecomp, denominatorDecomp, false);
48  static_cast<Multiplication *>(denominatorDecomp)->squashUnaryHierarchy();
49  }
50  if (r->sign() == Sign::Negative) {
51  result = new Opposite(result, false);
52  }
53  replaceWith(result, true);
54  if (result == numeratorDecomp) {
55  return static_cast<Multiplication *>(numeratorDecomp)->squashUnaryHierarchy();
56  }
57  static_cast<Multiplication *>(numeratorDecomp)->squashUnaryHierarchy();
58  return result;
59 }
60 
61 Expression * Factor::createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context & context, AngleUnit angleUnit) {
62  assert(!i.isZero());
63  i.setNegative(false);
64  Multiplication * m = new Multiplication();
65  if (i.isOne()) {
66  m->addOperand(new Rational(i));
67  return m;
68  }
70  Integer coefficients[Arithmetic::k_maxNumberOfPrimeFactors];
72  int index = 0;
73  if (coefficients[0].isMinusOne()) {
74  delete m;
75  return new Undefined();
76  }
77  while (!coefficients[index].isZero() && index < Arithmetic::k_maxNumberOfPrimeFactors) {
78  Expression * factor = new Rational(factors[index]);
79  if (!coefficients[index].isOne()) {
80  Expression * exponent = new Rational(coefficients[index]);
81  factor = new Power(factor, exponent, false);
82  }
83  m->addOperand(factor);
84  index++;
85  }
86  return m;
87 }
88 
89 }
friend class Division
Definition: expression.h:25
#define assert(e)
Definition: assert.h:9
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
Definition: expression.cpp:85
Expression * editableOperand(int i)
Definition: expression.h:176
friend class Rational
Definition: expression.h:18
friend class Power
Definition: expression.h:21
friend class Opposite
Definition: expression.h:62
static void PrimeFactorization(const Integer *i, Integer *outputFactors, Integer *outputCoefficients, int outputLength)
Definition: arithmetic.cpp:39
const Expression * m_operands[T]
friend class Multiplication
Definition: expression.h:20
static constexpr int k_maxNumberOfPrimeFactors
Definition: arithmetic.h:15
friend class Factor
Definition: expression.h:24
Type type() const override
Definition: factor.cpp:16
virtual Type type() const =0
Expression * clone() const override
Definition: factor.cpp:20
friend class Undefined
Definition: expression.h:17