Numworks Epsilon  1.4.1
Graphing Calculator Operating System
factorial.cpp
Go to the documentation of this file.
1 #include <poincare/factorial.h>
2 #include "layout/string_layout.h"
4 #include <poincare/rational.h>
5 #include <poincare/undefined.h>
6 #include <poincare/symbol.h>
8 #include <ion.h>
9 extern "C" {
10 #include <assert.h>
11 }
12 #include <cmath>
13 
14 namespace Poincare {
15 
16 Factorial::Factorial(const Expression * argument, bool clone) :
17  StaticHierarchy<1>(&argument, clone)
18 {
19 }
20 
22  return Type::Factorial;
23 }
24 
26  Factorial * a = new Factorial(m_operands[0], true);
27  return a;
28 }
29 
30 /* Layout */
31 
32 bool Factorial::needParenthesisWithParent(const Expression * e) const {
33  return e->type() == Type::Factorial;
34 }
35 
36 /* Simplification */
37 
38 Expression * Factorial::shallowReduce(Context& context, AngleUnit angleUnit) {
39  Expression * e = Expression::shallowReduce(context, angleUnit);
40  if (e != this) {
41  return e;
42  }
43 #if MATRIX_EXACT_REDUCING
44  if (operand(0)->type() == Type::Matrix) {
45  return SimplificationEngine::map(this, context, angleUnit);
46  }
47 #endif
48  if (operand(0)->type() == Type::Rational) {
49  Rational * r = static_cast<Rational *>(editableOperand(0));
50  if (!r->denominator().isOne() || r->sign() == Sign::Negative) {
51  return replaceWith(new Undefined(), true);
52  }
53  if (Integer(k_maxOperandValue).isLowerThan(r->numerator())) {
54  return this;
55  }
56  Rational * fact = new Rational(Integer::Factorial(r->numerator()));
57  return replaceWith(fact, true);
58  }
59  if (operand(0)->type() == Type::Symbol) {
60  Symbol * s = static_cast<Symbol *>(editableOperand(0));
61  if (s->name() == Ion::Charset::SmallPi || s->name() == Ion::Charset::Exponential) {
62  return replaceWith(new Undefined(), true);
63  }
64  }
65  return this;
66 }
67 
68 template<typename T>
69 Complex<T> Factorial::computeOnComplex(const Complex<T> c, AngleUnit angleUnit) {
70  T n = c.a();
71  if (c.b() != 0 || std::isnan(n) || n != (int)n || n < 0) {
72  return Complex<T>::Float(NAN);
73  }
74  T result = 1;
75  for (int i = 1; i <= (int)n; i++) {
76  result *= (T)i;
77  if (std::isinf(result)) {
78  return Complex<T>::Float(result);
79  }
80  }
81  return Complex<T>::Float(std::round(result));
82 }
83 
84 ExpressionLayout * Factorial::privateCreateLayout(PrintFloat::Mode floatDisplayMode, ComplexFormat complexFormat) const {
85  assert(floatDisplayMode != PrintFloat::Mode::Default);
86  assert(complexFormat != ComplexFormat::Default);
87  ExpressionLayout * childrenLayouts[2];
88  childrenLayouts[0] = operand(0)->createLayout(floatDisplayMode, complexFormat);
89  childrenLayouts[1] = new StringLayout("!", 1);
90  return new HorizontalLayout(childrenLayouts, 2);
91 }
92 
93 int Factorial::writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits) const {
94  if (bufferSize == 0) {
95  return -1;
96  }
97  buffer[bufferSize-1] = 0;
98  int numberOfChar = operand(0)->writeTextInBuffer(buffer, bufferSize, numberOfSignificantDigits);
99  if (numberOfChar >= bufferSize-1) {
100  return numberOfChar;
101  }
102  buffer[numberOfChar++] = '!';
103  buffer[numberOfChar] = 0;
104  return numberOfChar;
105 }
106 
107 #if 0
108 int Factorial::simplificationOrderGreaterType(const Expression * e) const {
109  if (SimplificationOrder(operand(0),e) == 0) {
110  return 1;
111  }
112  return SimplificationOrder(operand(0), e);
113 }
114 
115 int Factorial::simplificationOrderSameType(const Expression * e) const {
116  return SimplificationOrder(operand(0), e->operand(0));
117 }
118 #endif
119 
120 }
#define NAN
Definition: math.h:30
Factorial(const Expression *argument, bool clone=true)
Definition: factorial.cpp:16
#define assert(e)
Definition: assert.h:9
#define isinf(x)
Definition: math.h:44
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
Definition: expression.cpp:85
#define T(x)
Definition: events.cpp:26
friend class Symbol
Definition: expression.h:72
int simplificationOrderSameType(const Expression *e, bool canBeInterrupted) const override
c(generic_all_nodes)
static Integer Factorial(const Integer &i)
Definition: integer.cpp:271
Expression * editableOperand(int i)
Definition: expression.h:176
friend class Rational
Definition: expression.h:18
static int SimplificationOrder(const Expression *e1, const Expression *e2, bool canBeInterrupted=false)
Definition: expression.cpp:226
#define round(x)
Definition: math.h:192
const Expression * m_operands[T]
ExpressionLayout * createLayout(PrintFloat::Mode floatDisplayMode=PrintFloat::Mode::Default, ComplexFormat complexFormat=ComplexFormat::Default) const
Definition: expression.cpp:244
#define isnan(x)
Definition: math.h:43
static Complex< T > Float(T x)
Definition: complex.cpp:23
Expression * clone() const override
Definition: factorial.cpp:25
Type type() const override
Definition: factorial.cpp:21
const Expression * operand(int i) const
Definition: expression.cpp:78
virtual Type type() const =0
friend class Undefined
Definition: expression.h:17
virtual int writeTextInBuffer(char *buffer, int bufferSize, int numberOfSignificantDigits=PrintFloat::k_numberOfStoredSignificantDigits) const =0