// Returns a / b. Integer Integer::divide(Integer& a, Integer& b) const { Integer q, row; int asign = a.sign(); int bsign = b.sign(); int i; q.set_size(a.size()); a.set_sign(PLUS); b.set_sign(PLUS); for (i = a.size() - 1; i >= 0; i--) { row <<= 1; row[0] = a[i]; q[i] = 0; while (row >= b) { q[i]++; row -= b; } } q.adjust(); if (q == ZERO) q.set_sign(PLUS); else q.set_sign(asign * bsign); a.set_sign(asign); b.set_sign(bsign); return q; }
// Return a * b. This method is known as "Long Multiplication". // Complexity: O(n^2) Integer Integer::multiply(Integer& a, Integer& b) const { Integer ans; unsigned int i, j, k, n, carry_mult, carry_sum; for (i = 0; i < a.size(); i++) { carry_mult = carry_sum = 0; k = i; // Shifting for (j = 0; j < b.size(); j++) { n = a[i] * b[j] + carry_mult; carry_mult = n / BASE; n = ans[k] + n % BASE + carry_sum; carry_sum = n / BASE; ans[k] = n % BASE; k++; } if (carry_sum > 0 || carry_mult > 0) { ans[k++] = carry_sum + carry_mult; } ans.set_size(k); } if (ans == ZERO) ans.set_sign(PLUS); else ans.set_sign(a.sign() * b.sign()); return ans; }
// Compare a with b, possible results are: // 0 : a and b are equals. // PLUS(1) : b > a // MINUS(-1) : b < a int Integer::compare(const Integer& a, const Integer& b) const { if (a.sign() == MINUS && b.sign() == PLUS) { return PLUS; } if (a.sign() == PLUS && b.sign() == MINUS) { return MINUS; } if (b.size() > a.size()) { return PLUS * a.sign(); } if (a.size() > b.size()) { return MINUS * a.sign(); } for (int i = a.size() - 1; i >= 0; i--) { if (a[i] > b[i]) { return MINUS * a.sign(); } if (b[i] > a[i]) { return PLUS * a.sign(); } } return 0; }
// a and b are positive integers. Integer Integer::subtract(Integer& a, Integer& b) const { Integer ans; int borrow = 0, n; // Three special cases: // a - (-b) == a + b // -a - b == -a + (-b) // -a - (-b) == -a + b if (a.sign() == MINUS || b.sign() == MINUS) { b.set_sign(MINUS * b.sign()); ans = add(a, b); b.set_sign(MINUS * b.sign()); return ans; } if (a == b) { return ZERO; } if (a < b) { ans = subtract(b, a); ans.set_sign(MINUS); return ans; } unsigned int i; for (i = 0; i < a.size(); i++) { n = a[i] - b[i] - borrow; borrow = (n < 0) ? 1 : 0; if (n < 0) { n += BASE; } ans[i] = n; } ans.set_size(i); ans.adjust(); ans.set_sign(PLUS); return ans; }
// Returns a new integer c = a + b Integer Integer::add(Integer &a, Integer &b) const { Integer c; int carry = 0, i; if (a.sign() == b.sign()) { c.set_sign(a.sign()); } else { if (a.sign() == MINUS) { a.set_sign(PLUS); c = subtract(b, a); a.set_sign(MINUS); } else { b.set_sign(PLUS); c = subtract(a, b); b.set_sign(MINUS); } return c; } int max = std::max(a.size(), b.size()); int n; for (i = 0; i < max; i++) { n = carry + a[i] + b[i]; c[i] = n % BASE; carry = n / BASE; } if (carry > 0) { c[i++] = carry; } c.set_size(i); c.adjust(); return c; }
// Returns the absolute value of (*this). Integer Integer::abs() const { Integer temp = *this; temp.set_sign(temp.sign() * temp.sign()); return temp; }
Decimal Type::createDecimal( const Integer& value ) { assert( value.trivial() ); Decimal tmp( value.value(), value.sign() ); return tmp; }