예제 #1
0
파일: bignum.cpp 프로젝트: grablisting/ray
bignum bignum_popzeroes(bignum& c)
{
	if (c.size() > 1)
	{
		while (c.size() > 1 && c.back() == 0)
			c.pop_back();
	}
	return c;
}
예제 #2
0
파일: bignum.cpp 프로젝트: grablisting/ray
void bignum_print(ostream& print, bignum& c)
{
	c = bignum_popzeroes(c);
	
	cout << c.back();
	if (c.size() - 2 >= 0)
	{
		for (unsigned int i = c.size()-2; i + 1 > 0; i--)
			cout << setfill('0') << setw(3) << c[i];
	}
}
예제 #3
0
파일: bignum.cpp 프로젝트: grablisting/ray
bignum bignum_subtract(bignum& a, bignum& b)
{	
	bignum c;
	if (b.size() > a.size())
		c.push_back(0);
	else if (a.size() == b.size() && b.back() > a.back())
		c.push_back(0);
	else
	{
		int k;
		for (unsigned int i = 0; i < a.size() + b.size(); i++)
		{
			k = 0;
		
			if (i < a.size())
				k += a[i];
		
			if (i < b.size())
				k -= b[i];
	
			c.push_back(k);
		}
		
		for (unsigned int i = 0; i < c.size() - 1; i++)
		{
			while (c[i] < 0)
			{
				c[i + 1] -= 1;
				c[i] += BASE;
			}
		}
	}
	c = bignum_popzeroes(c);
	return c;
}
예제 #4
0
파일: bignum.cpp 프로젝트: grablisting/ray
bignum bignum_multiply(bignum& a, bignum& b)
{
	bignum c(a.size() + b.size() + 1);

	for (unsigned int i = 0; i < a.size(); i++)
	{
		for (unsigned int j = 0; j < b.size(); j++)
		{
			c[i + j] += a[i] * b[j];
		}
		c = bignum_carry(c);
	}
	c = bignum_popzeroes(c);
	return c;
}
예제 #5
0
bool operator<(const bignum& a, const bignum& b)
{
    if (a.sign and !b.sign)
        return true;
    if (!a.sign and b.sign)
        return false;
    // same sign
    if (a.size() != b.size())
        // a is shorter XOR a is negative
        return (a.size() < b.size()) != a.sign;
    // also same length
    pair<b_crit, b_crit> m = mismatch(a.rbegin(), a.rend(), b.rbegin());
    if (m.first == a.rend())
        return false; // a == b
    return (*m.first < *m.second) != a.sign;
}
예제 #6
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;
}
예제 #7
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();
}
예제 #8
0
bool bignum::operator<(bignum a)
{
	if(this->sign() != a.sign())
	{
		if(this->sign()=='-')
			return true;
		else
 			return false;
	}
	if(this->size()>a.size())
		return false;
	if(this->size()<a.size())
		return true;
	for(int i=0;i<a.size();i++)
	{
		if(this->x.num[i]<a.x.num[i])
			return true;
	}
	return false;
}
예제 #9
0
파일: bignum.cpp 프로젝트: grablisting/ray
bignum bignum_add(bignum& a, bignum& b)
{
	bignum c;
	int k;
	
	for (unsigned int i = 0; i < a.size() + b.size(); i++)
	{
		k = 0;
		
		if (i < a.size())
			k += a[i];
		
		if (i < b.size())
			k += b[i];
		
		c.push_back(k);
	}
	c = bignum_carry(c);
	c = bignum_popzeroes(c);
	return c;
}
예제 #10
0
파일: bignum.cpp 프로젝트: grablisting/ray
bignum bignum_carry(bignum& c)
{
	for (unsigned int i = 0; i < c.size() - 1; i++)
	{
		if (c[i] >= BASE)
		{
			c[i + 1] += c[i] / BASE;
			c[i] = c[i] % BASE;
		}
	}
	return c;
}
예제 #11
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());
}