Я пишу десятичный множитель в C ++. Множитель реализуется путем взятия двух целых чисел, представленных как векторы цифр. Каждый вектор хранит свои цифры в обратном порядке, для более простого представления степенями десяти. Например, 3497 = 3 * 10 ^ 3 + 4 * 10 ^ 2 + 9 * 10 ^ 1 + 7 * 10 ^ 0 и сохраняется в векторе как {7, 9, 4, 3}. Таким образом, каждый индекс вектора представляет соответствующую цифру десятичной цифры в целом числе.
Однако у меня есть некоторые ошибки в моем умножении. Умножение 1-значное x 1-значное и 2-значное x 1-значное отлично работает, но оно разбивается на 2-значное x 2-значное. Я вполне уверен, что исправление этой ошибки исправит все другие ошибки с n-цифрой x m-цифрой. Мой код для методов умножения и сложения приведен ниже.
vector<int> multiply(vector<int> &a, vector<int> &b) {
// check for emptiness
if(a.size() == 0)
return b;
else if(b.size() == 0)
return a;
unsigned int i; // increment counter
// compensate for size differences
if(a.size() > b.size())
for(i = 0; i < a.size()-b.size(); ++i)
b.push_back(0);
else
for(i = 0; i < b.size()-a.size(); ++i)
a.push_back(0);
int c = 0; // carry value
int temp; // temporary integer
vector<int> p; // product vector
vector<int> s; // sum vector
s.push_back(0); // initialize to 0
// multiply each digit of a by an index of b
for(i = 0; i < b.size(); ++i) {
// skip digits of 0
if(b[i] == 0)
continue;
p.resize(i,0); // resize p and add 0s
// multiply b[i] by each digit of a
for(unsigned int j = 0; j < a.size(); ++j) {
temp = c + b[i] * a[j]; // calculate temporary value
// two cases
if(temp > 9) {
c = temp / 10; // new carry
p.push_back(temp % 10);
}
else {
c = 0;
p.push_back(temp);
}
}
// append carry if relevant
if(c != 0)
p.push_back(c);
// sum p and s
s = add(p, s);
p.clear(); // empty p
}
return s; // return summed vector (total product)
}
vector<int> add(vector<int> &a, vector<int> &b) {
// check for emptiness
if(a.size() == 0)
return b;
else if(b.size() == 0)
return a;
unsigned int i; // increment counter
// compensate size differences
if(a.size() > b.size())
for(i = 0; i < a.size()-b.size(); ++i)
b.push_back(0);
else
for(i = 0; i < b.size()-a.size(); ++i)
a.push_back(0);
int c = 0; // carry value
vector<int> s; // sum vector
int temp; // temporary value
// iterate through decimal vectors
for(i = 0; i < a.size(); ++i) {
temp = c + a[i] + b[i]; // sum three terms
// two cases
if(temp > 9) {
c = temp / 10; // new carry
s.push_back(temp % 10); // push back remainder
}
else {
c = 0;
s.push_back(temp);
}
}
// append carry if relevant
if(c != 0)
s.push_back(c);
return s; // return sum
}
Несколько тестовых случаев:
45 * 16 возвращает 740 (должно быть 720)
34 * 18 возвращает 542 (должно быть 532)
67 * 29 возвращает 2003 (должно быть 1943)
28 * 12 возвращает 336 (правильно)
Единственной проблемой, о которой я мог подумать, была бы проблема с переносами, но, кажется, все проверяется, когда я прохожу код. Кто-нибудь может увидеть ошибку? Или я совершенно неверно к этому отношусь?