mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-25 00:30:46 +01:00
[poincare] In Integer, create a static method Division returning a
struct Change-Id: I1eb84a79c69e15cd815df87fe7b56bc7327c53be
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user