c++實現超大整數的乘法

構思

c++已實現因數不大於UINT32_MAX(42949 67295)的乘法,故而可以將超大整數每9位分成一段,然後循環分段相乘,再在末尾填零,然後再做加和。這裏就僅需要實現超長整數的加法。

代碼

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
//UINT32_MAX = 42949 67295

class BigInt;

//實現字符串超長整數的加法
class Addend {
	friend BigInt;
public:
	Addend():m_str("0") {};
	Addend(const string& a) { m_str = a; }
	Addend(uint64_t src, size_t offset) {
		m_str = to_string(src);
		for (size_t i = 0; i < offset; ++i) {
			m_str.push_back('0');
		}
	}
	void clear() {
		m_str.clear();
	}
	const Addend &add(Addend& sum, const Addend& other) const {
		sum.clear();
		Addend lesser;
		const auto* bigger = this;
		const auto sz_other = other.m_str.size();
		const auto sz = m_str.size();
		if (sz_other > sz) {
			lesser.m_str.clear();
			bigger = &other;
			for (size_t i = sz_other - sz; i > 0; --i) {
				lesser.m_str.push_back('0');
			}
			lesser.m_str.append(m_str);
		}
		else if (sz_other < sz) {
			lesser.m_str.clear();
			for (size_t i = sz - sz_other; i > 0; --i) {
				lesser.m_str.push_back('0');
			}
			lesser.m_str.append(other.m_str);
		}
		else {
			lesser = other;
		}

		uint8_t sum_single;
		bool carry = false;
		vector<char> tmpsum;
		for (int i = bigger->m_str.size() - 1; i >= 0; --i) {
			if (carry) {
				sum_single = 1;
			}
			else {
				sum_single = 0;
			}
			carry = false;
			sum_single += bigger->m_str.c_str()[i] + lesser.m_str.c_str()[i] - '0' - '0';
			if (sum_single > 9) {
				sum_single -= 10;
				carry = true;
			}
			tmpsum.push_back(sum_single + '0');
		}
		if (carry) {
			sum.m_str.push_back('1');
		}
		for (auto it = tmpsum.crbegin(); it != tmpsum.crend(); ++it) {
			sum.m_str.push_back(*it);
		}
		return sum;
	};
	const string& getstr() const { return m_str; };
protected:
	std::string m_str;
};
//實現超長整數的乘法
class BigInt {
public:
	BigInt() {};
	BigInt(const std::string& src);
	const std::string &print_oct();
	const Addend &mult(Addend& pow, const BigInt& divisor) const;
protected:
	vector<uint64_t> m_data;//每9位截取出一個整數,先低後高
	Addend m_oct;
};

BigInt::BigInt(const std::string& src) {
	int r = src.size();
	int l = src.size() - 9;
	if (l < 0) {
		l = 0;
	}
	uint64_t tmp;
	do {
		tmp = stoull(src.substr(l, r - l));
		m_data.push_back(tmp);
		if (l == 0) {
			break;
		}
		r = l;
		l -= 9;
		if (l < 0) {
			l = 0;
		}
	} while (1);
	print_oct();
}

const std::string &BigInt::print_oct() {
	if (m_oct.m_str == "0") {
		m_oct.m_str.clear();
		for (auto it = m_data.crbegin(); it != m_data.crend(); ++it) {
			m_oct.m_str.append(to_string(*it));
		}
	}
	return m_oct.m_str;
}

const Addend &BigInt::mult(Addend& pow, const BigInt& divisor) const {
	uint64_t tmp;
	size_t i = 0;
	Addend powTmp;
	for (auto& eachsector : divisor.m_data) {
		size_t j = 0;
		for (auto& eachsectorme : m_data) {
			tmp = eachsector * eachsectorme;
			Addend tmpsum(tmp, i * 9 + j * 9);
			pow.add(powTmp, tmpsum);
			pow = powTmp;
			++j;
		}
		++i;
	}
	return pow;
}

int main() {
	while (true)
	{
		string input;
		cin >> input;
		BigInt divisor(input);
		Addend a(input);
		cout << "divisor=" << divisor.print_oct() << endl;
		Addend sum;
		cout << "sum=" << a.add(sum, a).getstr() << endl;
		Addend pow;
		divisor.mult(pow, divisor);
		cout << "pow=" << pow.getstr() << endl;
	}

	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章