Numworks Epsilon  1.4.1
Graphing Calculator Operating System
division_quotient.cpp
Go to the documentation of this file.
2 #include <poincare/rational.h>
3 #include <poincare/undefined.h>
4 
5 extern "C" {
6 #include <assert.h>
7 }
8 #include <cmath>
9 
10 namespace Poincare {
11 
14 }
15 
18  return a;
19 }
20 
21 Expression * DivisionQuotient::shallowReduce(Context& context, AngleUnit angleUnit) {
22  Expression * e = Expression::shallowReduce(context, angleUnit);
23  if (e != this) {
24  return e;
25  }
26  Expression * op0 = editableOperand(0);
27  Expression * op1 = editableOperand(1);
28 #if MATRIX_EXACT_REDUCING
29  if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) {
30  return replaceWith(new Undefined(), true);
31  }
32 #endif
33  if (op0->type() == Type::Rational) {
34  Rational * r0 = static_cast<Rational *>(op0);
35  if (!r0->denominator().isOne()) {
36  return replaceWith(new Undefined(), true);
37  }
38  }
39  if (op1->type() == Type::Rational) {
40  Rational * r1 = static_cast<Rational *>(op1);
41  if (!r1->denominator().isOne()) {
42  return replaceWith(new Undefined(), true);
43  }
44  }
45  if (op0->type() != Type::Rational || op1->type() != Type::Rational) {
46  return this;
47  }
48  Rational * r0 = static_cast<Rational *>(op0);
49  Rational * r1 = static_cast<Rational *>(op1);
50 
51  Integer a = r0->numerator();
52  Integer b = r1->numerator();
53  if (b.isZero()) {
54  return replaceWith(new Undefined(), true); // TODO: new Infinite(a.isNegative())
55  }
56  Integer result = Integer::Division(a, b).quotient;
57  return replaceWith(new Rational(result), true);
58 }
59 
60 template<typename T>
61 Complex<T> * DivisionQuotient::templatedApproximate(Context& context, AngleUnit angleUnit) const {
62  Expression * f1Input = operand(0)->approximate<T>(context, angleUnit);
63  Expression * f2Input = operand(1)->approximate<T>(context, angleUnit);
64  T f1 = f1Input->type() == Type::Complex ? static_cast<Complex<T> *>(f1Input)->toScalar() : NAN;
65  T f2 = f2Input->type() == Type::Complex ? static_cast<Complex<T> *>(f2Input)->toScalar() : NAN;
66  delete f1Input;
67  delete f2Input;
68  if (std::isnan(f1) || std::isnan(f2) || f1 != (int)f1 || f2 != (int)f2) {
69  return new Complex<T>(Complex<T>::Float(NAN));
70  }
71  return new Complex<T>(Complex<T>::Float(std::floor(f1/f2)));
72 }
73 
74 }
75 
#define NAN
Definition: math.h:30
friend class DivisionQuotient
Definition: expression.h:41
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
Definition: expression.cpp:85
Expression * approximate(Context &context, AngleUnit angleUnit=AngleUnit::Default) const
Definition: expression.cpp:338
Type type() const override
#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
static Complex< T > Float(T x)
Definition: complex.cpp:23
#define floor(x)
Definition: math.h:179
const Expression * operand(int i) const
Definition: expression.cpp:78
static IntegerDivision Division(const Integer &numerator, const Integer &denominator)
Definition: integer.cpp:281
friend class Undefined
Definition: expression.h:17