예제 #1
0
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;
}
예제 #2
0
// 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();
}
예제 #3
0
// 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();
}
예제 #4
0
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);
}
예제 #5
0
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());
}