mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-29 19:49:58 +02:00
[poincare] Implement Integer::Division in Z (relative integers)
Change-Id: I72ccd4afd8188b0389b1f32863ecb1af59581c04
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user