Numworks Epsilon  1.4.1
Graphing Calculator Operating System
least_common_multiple.cpp
Go to the documentation of this file.
2 #include <poincare/complex.h>
3 #include <poincare/rational.h>
4 #include <poincare/undefined.h>
5 #include <poincare/arithmetic.h>
6 
7 extern "C" {
8 #include <assert.h>
9 }
10 #include <cmath>
11 
12 namespace Poincare {
13 
16 }
17 
20  return a;
21 }
22 
23 Expression * LeastCommonMultiple::shallowReduce(Context& context, AngleUnit angleUnit) {
24  Expression * e = Expression::shallowReduce(context, angleUnit);
25  if (e != this) {
26  return e;
27  }
28  Expression * op0 = editableOperand(0);
29  Expression * op1 = editableOperand(1);
30 #if MATRIX_EXACT_REDUCING
31  if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) {
32  return replaceWith(new Undefined(), true);
33  }
34 #endif
35  if (op0->type() == Type::Rational) {
36  Rational * r0 = static_cast<Rational *>(op0);
37  if (!r0->denominator().isOne()) {
38  return replaceWith(new Undefined(), true);
39  }
40  }
41  if (op1->type() == Type::Rational) {
42  Rational * r1 = static_cast<Rational *>(op1);
43  if (!r1->denominator().isOne()) {
44  return replaceWith(new Undefined(), true);
45  }
46  }
47  if (op0->type() != Type::Rational || op1->type() != Type::Rational) {
48  return this;
49  }
50  Rational * r0 = static_cast<Rational *>(op0);
51  Rational * r1 = static_cast<Rational *>(op1);
52 
53  Integer a = r0->numerator();
54  Integer b = r1->numerator();
55  Integer lcm = Arithmetic::LCM(&a, &b);
56  return replaceWith(new Rational(lcm), true);
57 }
58 
59 template<typename T>
60 Complex<T> * LeastCommonMultiple::templatedApproximate(Context& context, AngleUnit angleUnit) const {
61  Expression * f1Input = operand(0)->approximate<T>(context, angleUnit);
62  Expression * f2Input = operand(1)->approximate<T>(context, angleUnit);
63  T f1 = f1Input->type() == Type::Complex ? static_cast<Complex<T> *>(f1Input)->toScalar() : NAN;
64  T f2 = f2Input->type() == Type::Complex ? static_cast<Complex<T> *>(f2Input)->toScalar() : NAN;
65  delete f1Input;
66  delete f2Input;
67  if (std::isnan(f1) || std::isnan(f2) || f1 != (int)f1 || f2 != (int)f2) {
68  return new Complex<T>(Complex<T>::Float(NAN));
69  }
70  if (f1 == 0.0f || f2 == 0.0f) {
71  return new Complex<T>(Complex<T>::Float(0));
72  }
73  int a = (int)f2;
74  int b = (int)f1;
75  if (f1 > f2) {
76  b = a;
77  a = (int)f1;
78  }
79  int product = a*b;
80  int r = 0;
81  while((int)b!=0){
82  r = a - ((int)(a/b))*b;
83  a = b;
84  b = r;
85  }
86  return new Complex<T>(Complex<T>::Float(product/a));
87 }
88 
89 }
90 
static Integer LCM(const Integer *i, const Integer *j)
Definition: arithmetic.cpp:6
#define NAN
Definition: math.h:30
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
Definition: expression.cpp:85
Expression * approximate(Context &context, AngleUnit angleUnit=AngleUnit::Default) const
Definition: expression.cpp:338
#define T(x)
Definition: events.cpp:26
Expression * editableOperand(int i)
Definition: expression.h:176
friend class Rational
Definition: expression.h:18
Expression * clone() const override
const Expression * m_operands[T]
#define isnan(x)
Definition: math.h:43
friend class LeastCommonMultiple
Definition: expression.h:54
static Complex< T > Float(T x)
Definition: complex.cpp:23
const Expression * operand(int i) const
Definition: expression.cpp:78
friend class Undefined
Definition: expression.h:17