[poincare] In Integer, create a static method Division returning a

struct

Change-Id: I1eb84a79c69e15cd815df87fe7b56bc7327c53be
This commit is contained in:
Émilie Feral
2017-09-26 13:22:59 +02:00
parent 59a4992a7d
commit febcea6955
2 changed files with 29 additions and 42 deletions

View File

@@ -7,6 +7,8 @@
namespace Poincare {
struct IntegerDivision;
class Integer : public StaticHierarchy<0> {
public:
typedef int32_t native_int_t;
@@ -40,6 +42,7 @@ public:
static Integer Addition(const Integer & i, const Integer & j);
static Integer Subtraction(const Integer & i, const Integer & j);
static Integer Multiplication(const Integer & i, const Integer & j);
static IntegerDivision Division(const Integer & numerator, const Integer & denominator);
//static Integer Division(const Integer & i, const Integer & j);
//static IntegerDivision division(const Integer & i, const Integer & j);
private:
@@ -69,14 +72,9 @@ private:
static_assert(sizeof(double_native_uint_t) == 2*sizeof(native_uint_t), "double_native_uint_t should be twice the size of native_uint_t");
};
class IntegerDivision {
public:
IntegerDivision(const Integer & numerator, const Integer & denominator);
const Integer & quotient() { return m_quotient; }
const Integer & remainder() { return m_remainder; }
private:
Integer m_quotient;
Integer m_remainder;
struct IntegerDivision {
Integer quotient;
Integer remainder;
};
}

View File

@@ -205,11 +205,24 @@ Integer Integer::Multiplication(const Integer & a, const Integer & b) {
return Integer(digits, productSize, a.m_negative != b.m_negative);
}
/*Integer Integer::Division(const Integer & a, const Integer & b) {
return IntegerDivision(a, b).quotient();
}
*/
IntegerDivision Integer::Division(const Integer & numerator, const Integer & denominator) {
// FIXME: First, test if denominator is zero.
if (numerator.isLowerThan(denominator)) {
IntegerDivision div = {.quotient = 0, .remainder = Integer::Addition(numerator, Integer(0))};
// FIXME: This is a ugly way to bypass creating a copy constructor!
return div;
}
// Recursive case
IntegerDivision div = Division(numerator, Integer::Addition(denominator, denominator));
div.quotient = Integer::Addition(div.quotient, div.quotient);
if (!(div.remainder.isLowerThan(denominator))) {
div.remainder = Integer::Subtraction(div.remainder, denominator);
div.quotient = Integer::Addition(div.quotient, Integer(1));
}
return div;
}
// Private methods
@@ -296,7 +309,7 @@ int Integer::identifier() const {
/*
Integer Integer::divide_by(const Integer &other) const {
return IntegerDivision(*this, other).m_quotient;
return Division(*this, other).quotient;
}
@@ -465,17 +478,17 @@ ExpressionLayout * Integer::privateCreateLayout(FloatDisplayMode floatDisplayMod
char buffer[255];
Integer base = Integer(10);
IntegerDivision d = IntegerDivision(*this, base);
IntegerDivision d = Division(*this, base);
int size = 0;
if (isEqualTo(Integer(0))) {
buffer[size++] = '0';
}
while (!(d.remainder().isEqualTo(Integer(0)) &&
d.quotient().isEqualTo(Integer(0)))) {
while (!(d.remainder.isEqualTo(Integer(0)) &&
d.quotient.isEqualTo(Integer(0)))) {
assert(size<255); //TODO: malloc an extra buffer
char c = char_from_digit(d.remainder().digit(0));
char c = char_from_digit(d.remainder.digit(0));
buffer[size++] = c;
d = IntegerDivision(d.quotient(), base);
d = Division(d.quotient, base);
}
buffer[size] = 0;
@@ -489,28 +502,4 @@ ExpressionLayout * Integer::privateCreateLayout(FloatDisplayMode floatDisplayMod
return new StringLayout(buffer, size);
}
// Class IntegerDivision
IntegerDivision::IntegerDivision(const Integer & numerator, const Integer & denominator) :
m_quotient(Integer(0)),
m_remainder(Integer(0))
{
// FIXME: First, test if denominator is zero.
if (numerator.isLowerThan(denominator)) {
m_quotient = Integer(0);
m_remainder = Integer::Addition(numerator, Integer(0));
// FIXME: This is a ugly way to bypass creating a copy constructor!
return;
}
// Recursive case
*this = IntegerDivision(numerator, Integer::Addition(denominator, denominator));
m_quotient = Integer::Addition(m_quotient, m_quotient);
if (!(m_remainder.isLowerThan(denominator))) {
m_remainder = Integer::Subtraction(m_remainder, denominator);
m_quotient = Integer::Addition(m_quotient, Integer(1));
}
}
}