構思
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;
}