bignum operator*(const bignum& a, const bignum& b) { if (a.empty() or b.empty()) return bignum(); if (a.size() + b.size() < 19) { long long x = a; long long y = b; return x*y; } const unsigned n = max(a.size(), b.size()); const unsigned h = n/2; bignum w, x; // a = 10^h * w + x bignum y, z; // b = 10^h * y + z b_cit ha, hb; ha = (h > a.size()) ? a.end() : a.begin()+h; hb = (h > b.size()) ? b.end() : b.begin()+h; x.assign(a.begin(), ha); w.assign(ha, a.end()); x.clean(); w.clean(); z.assign(b.begin(), hb); y.assign(hb, b.end()); z.clean(); y.clean(); bignum p = w*y; bignum q = x*z; bignum r = (w+x) * (y+z); // result = 10^(2*h) * p + 10^h * (r-p-q) + q bignum result; result.resize(a.size() + b.size()); fill(result.begin(), result.begin()+2*h, 0); copy(p.begin(), p.end(), result.begin() + 2*h); result.clean(); r -= p+q; // p = 10^h * r p.resize(r.size() + h); fill(p.begin(), p.begin()+h, 0); copy(r.begin(), r.end(), p.begin()+h); p.clean(); result += q; result += p; result.sign = a.sign != b.sign; return result; }
// a += b, ignoring signal void add_inplace(bignum& a, const bignum& b) { a.resize( 1 + max(a.size(), b.size()) ); b_it i; b_cit j; Digit carry = 0; for (i=a.begin(), j=b.begin(); i!=a.end(); ++i) { *i += (j!=b.end() ? *j++ : 0) + carry; if (*i >= bignum::base) { *i -= bignum::base; carry = 1; } else carry = 0; } assert(carry == 0); a.clean(); }
// a -= b, ignoring signal, assume a is larger than b void subtract_inplace(bignum& a, const bignum& b) { bignum x=a, y=b; b_it i; b_cit j; Digit borrow = 0; for (i=a.begin(), j=b.begin(); i!=a.end(); ++i) { *i -= (j!=b.end() ? *j++ : 0) + borrow; if (*i < 0) { *i += bignum::base; borrow = 1; } else borrow = 0; } assert(borrow == 0); a.clean(); }
void doubleNum(bignum & num) { int carry = 0; for(bignum::iterator p = num.begin(); p != num.end(); p++) { *p *= 2; *p += carry; carry = (*p >= 10) ? 1 : 0; *p -= carry * 10; } if (carry != 0) num.push_back(carry); }
bool operator==(const bignum& a, const bignum& b) { return a.sign == b.sign and a.size() == b.size() and equal(a.begin(), a.end(), b.begin()); }