InfInt karatsubaMult(string x, string y)
{
	InfInt *result = new InfInt(0);
	int m = makeEqualLength(x, y);

	if(m == 0)
		return *result;

	size_t sz = 0;
	if( x.length() == 1 || y.length() == 1 ) {
		result = new InfInt(stoull(x, &sz, 0) * stoull(y, &sz, 0));
		return *result;
	}

	// m2 + m2Rest = m
	int m2 = m/2;
	int m2Rest = m - m2;

	string xl = x.substr(0, m2);
	string xr = x.substr(m2, m2Rest);
	string yl = y.substr(0, m2);
	string yr = y.substr(m2, m2Rest);

	InfInt z0 = karatsubaMult(xr, yr);
	InfInt z1 = karatsubaMult(add(xl, xr), add(yl, yr));
	InfInt z2 = karatsubaMult(xl, yl);
	*result = (z2 * basePower(*INFINTBASE10, 2*m2) + ((z1-z2-z0) * basePower(*INFINTBASE10, m2)) + z0);

	return *result;
}
Exemple #2
0
BigInt BigInt::karatsubaMult(const BigInt& a, const BigInt& b)
{
	int minSize = std::min(a.size(), b.size());
	if (minSize < 30) {
		return a * b;
	}

	BigInt x0, x1, y0, y1;
	BigInt z0, z1, z2;
	int mid = minSize / 2;

	x0.digits.resize(mid);
	x1.digits.resize(a.digits.size() - mid);

	y0.digits.resize(mid);
	y1.digits.resize(b.digits.size() - mid);

	copy(a.digits.begin(), a.digits.begin() + mid, x0.digits.begin());
	copy(a.digits.begin() + mid, a.digits.end(), x1.digits.begin());

	copy(b.digits.begin(), b.digits.begin() + mid, y0.digits.begin());
	copy(b.digits.begin() + mid, b.digits.end(), y1.digits.begin());

	z0 = karatsubaMult(x0, y0);
	z1 = karatsubaMult(x1, y1);
	z2 = (karatsubaMult(x0 + x1, y0 + y1) - z1) - z0;

	padZeros(z2, mid);
	padZeros(z1, 2*mid);

	return z0 + z1 + z2;
}