[poincare] Implement Integer::Division in Z (relative integers)

Change-Id: I72ccd4afd8188b0389b1f32863ecb1af59581c04
This commit is contained in:
Émilie Feral
2017-09-28 16:17:06 +02:00
parent 4ffa26be2b
commit b5c06fd22b
3 changed files with 52 additions and 14 deletions

View File

@@ -277,22 +277,35 @@ Integer Integer::Multiplication(const Integer & a, const Integer & b) {
}
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;
if (!numerator.isNegative() && !denominator.isNegative()) {
return udiv(numerator, denominator);
}
// 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));
Integer absNumerator = numerator;
absNumerator.setNegative(false);
Integer absDenominator = denominator;
absDenominator.setNegative(false);
IntegerDivision usignedDiv = udiv(absNumerator, absDenominator);
if (usignedDiv.remainder.isEqualTo(Integer(0))) {
if (!numerator.isNegative() || !denominator.isNegative()) {
usignedDiv.quotient.setNegative(true);
}
return usignedDiv;
}
return div;
if (numerator.isNegative()) {
if (denominator.isNegative()) {
usignedDiv.remainder.setNegative(true);
usignedDiv.quotient = Addition(usignedDiv.quotient, Integer(1));
usignedDiv.remainder = Integer::Subtraction(usignedDiv.remainder, denominator);
} else {
usignedDiv.quotient.setNegative(true);
usignedDiv.quotient = Subtraction(usignedDiv.quotient, Integer(1));
usignedDiv.remainder = Integer::Subtraction(denominator, usignedDiv.remainder);
}
} else {
assert(denominator.isNegative());
usignedDiv.quotient.setNegative(true);
}
return usignedDiv;
}
// Private methods
@@ -379,6 +392,24 @@ Integer Integer::addition(const Integer & a, const Integer & b, bool inverseBNeg
}
}
IntegerDivision Integer::udiv(const Integer & numerator, const Integer & denominator) {
assert(!numerator.isNegative() && !denominator.isNegative());
// FIXME: First, test if denominator is zero.
if (numerator.isLowerThan(denominator)) {
IntegerDivision div = {.quotient = 0, .remainder = numerator};
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;
}
int Integer::identifier() const {
assert(m_numberOfDigits > 0);
int sign = m_negative ? -1 : 1;