friend BigInt operator - (const BigInt& a, const BigInt& b) { // precondition: a >= b assert(b <= a); const int N = a.splits.size(); const int M = b.splits.size(); BigInt ret; ret.splits.resize(N); int borrow = 0; for (int i = 0; i < N; i++) { int d = a.splits[i] - (i < M ? b.splits[i] : 0) - borrow; if (d < 0) { d += SPLIT_OVERFLOW; borrow = 1; } else { borrow = 0; } ret.splits[i] = d; } assert(borrow == 0); ret.canonicalize(); return ret; }
friend BigInt operator / (const BigInt &a, int d) { const int N = a.splits.size(); BigInt ret; ret.splits.resize(N); int64_t carry = 0; for (int i = N-1; i >= 0; i--) { int64_t x = carry * SPLIT_OVERFLOW + a.splits[i]; ret.splits[i] = x / d; carry = x % d; } ret.canonicalize(); return ret; }
static BigInt mul(const BigInt& a, const BigInt& b) { const int n = a.splits.size(); const int m = b.splits.size(); vector<int64_t> h(n+m+10); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { h[i+j] += 1LL * a.splits[i] * b.splits[j]; h[i+j+1] += h[i+j] / SPLIT_OVERFLOW; h[i+j] %= SPLIT_OVERFLOW; } } for (int i = 0; i < n+m+9; i++) { h[i+1] += h[i]/SPLIT_OVERFLOW; h[i] %= SPLIT_OVERFLOW; } BigInt c; c.splits.resize(n+m+10); for (int i = 0; i < n+m+10; i++) { c.splits[i] = h[i]; } c.canonicalize(); return c; }