Why are you putting the result in a global variable? Why not return the resulting vector from the functions?
I'm very suspicious of the firstTime global. When adding two numbers, it shouldn't matter if you're doing it for the first time or the billionth.
It looks like you're storing the numbers so that num[0] is the most significant digit and num[num.size()-1] is the least significant. I think the code will be a whole lot easier if you reverse this, so num[0] is the least significant. That way num[x] always represents the xth digit for any num. This will slightly complicate your input and output functions, but the math will be whole lot easier.
kemort's function isn't right. It doesn't compute the sum or carry right, it doesn't return any value and it doesn't allow for carrying in. A better version would be:
// add a, b, and carry, which must each be 0 or 1. returns the sum and sets the carry.
// Note that "carry" is an in/out parameter. On input it's the carry in, on output it's the carry out.
1 2 3 4 5 6
|
int add(int a, int b, int &carry)
{
int sum = a+ b + carry;
carry = sum/2;
return sum % 2;
}
|
Since you're storing each bit in an integer, you can
temporarily store a larger value in each bit position. The value of the number in that position will still be X * 2
n but we'll allow X to be any value. Then you just need a function that will "normalize" the number by cleaning it up so each bit position contains just a 0 or 1. The version below assumes that position 0 is the LSB. I've added a bunch of debugging statements so you can see how it works.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
string numToString(const vector<int> &num)
{
string result;
for (int i=num.size()-1; i>=0; --i) {
result += num[i]+'0';
}
return result;
}
void normalize(vector<int> &num)
{
int carry=0;
int sum;
cout << "normalizing " << numToString(num) << '\n';
// add each digit, accumulating the carry
for (unsigned i=0; i<num.size(); ++i) {
cout << num[i] << "+" << carry;
num[i] = add(0, num[i], carry);
cout << "=" << num[i] << " carry " << carry << '\n';
}
while (carry) {
cout << "0+" << carry;
num.push_back(add(0, 0, carry));
cout << "=" << num[num.size()-1] << " carry " << carry << '\n';
}
}
|
Now adding numbers gets easy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
vector<int> add(const vector<int> &a, const vector<int> &b)
{
unsigned sz = std::min(a.size(), b.size());
vector<int> result(std::max(a.size(), b.size()), 0);
size_t i;
// add the digits that they both have
for (i = 0; i < sz; ++i) {
result[i] = a[i]+b[i];
}
// one number may have more digits than the other.
// Check them each. One of these loops won't execute at all
for (i=sz; i<a.size(); ++i) {
result[i] = a[i];
}
for (i=sz; i<b.size(); ++i) {
result[i] = b[i];
}
normalize(result);
return result;
}
|
and a test:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
int main()
{
vector<int> a, b, c;
a.push_back(0);
a.push_back(1);
a.push_back(0);
a.push_back(0);
a.push_back(1);
b.push_back(1);
b.push_back(1);
b.push_back(0);
b.push_back(1);
b.push_back(1);
cout << "adding " << numToString(a) << " + " << numToString(b) << '\n';
c = add(a,b);
cout << "sum = " << numToString(c) << '\n';
}
|
adding 10010 + 11011
normalizing 21021
1+0=1 carry 0
2+0=0 carry 1
0+1=1 carry 0
1+0=1 carry 0
2+0=0 carry 1
0+1=1 carry 0
sum = 101101 |