#include <iostream>
#include <string>
using namespace std;
const int MAX_DIGITS = 20;
string GetAddend();
// PRE: User has been prompted for number.
// POST: Returns (as a string) characters representing a positive integer
// up to MAX_DIGITS long in base-10 notation.
void CopyDigits (string Number, int digits[]);
// PRE: Number holds a representation of a positive int that will fit within digits[].
// digits[] is at least MAX_DIGITS in size.
// POST: digits are copied into array, pushed to the 'right' i.e. high end of array.
//Example:
// Number == "789" MaxDigits = 6
// Array index --> 0 1 2 3 4 5
// contents --> 0 0 0 7 8 9
bool AddEmUp(const int Op1[], const int Op2[], int Result[]);
// PRE: All 3 arrays are MAX_DIGITS in size. Op1 and Op2 hold numbers
// as formatted by CopyDigits().
// POST: Sum is in Result[]. Function returns true if successful. On overflow
// the function returns false; in this case, Result holds the non-overflowed
// portion of the answer.
string BigNumToString(const int Number[]);
// PRE: Number[] is MAX_DIGITS in size and holds a number as formatted by other funcs.
// POST: returns string representation of the number.
int main()
{
int Addend1[MAX_DIGITS], Addend2[MAX_DIGITS], Result[MAX_DIGITS];
string NumStr;
char ch;
bool again;
do
{
cout << "Enter first number to be added, up to " << MAX_DIGITS << " digits long: ";
NumStr = GetAddend();
CopyDigits(NumStr, Addend1);
cout << "Enter second number to be added, same length: ";
NumStr = GetAddend();
CopyDigits(NumStr, Addend2);
if (!AddEmUp(Addend1, Addend2, Result))
{
cout << "Error: Integer overflow." << endl;
}
else // success!
{
NumStr = BigNumToString(Result);
cout << "Sum = " << NumStr << '.' << endl;
}
cout << "Another [Y/N]? ";
cin >> ch;
ch = tolower(ch);
again = (ch == 'y');
} while (again);
return 0;
}
string GetAddend()
{
string answer;
bool do_over;
do
{
do_over = false;
do
{
cin >> answer;
if (answer.length() > MAX_DIGITS)
cout << "That's too long, try again." << endl;
} while (answer.length() > MAX_DIGITS);
for (int k = 0; k < answer.length(); k++)
{
if (answer[k] < '0' || answer[k] > '9')
do_over = true;
}
if (do_over)
cout << "Number can't contain non-numeric characters. Try again." << endl;
} while (do_over);
return answer;
}
void CopyDigits (string Number, int digits[])
{
int idx, tmp;
for (idx = 0; idx < MAX_DIGITS; idx++)
digits[idx] = 0;
// copy digits of NumStr into digits array, as integers
tmp = Number.length() - 1; // index of last character in Number
// copy into digits array.
for (idx = 0; idx <= tmp; idx++)
digits[MAX_DIGITS - idx - 1] = int(Number[tmp-idx]) - int('0');
// this method relies on the ASCII value of the characters, and
// thus is limited to certain hardware platforms. See the function
// BigNumToString(), below, for another method that's more portable.
}
bool AddEmUp(const int Op1[], const int Op2[], int Result[])
{
int tmp, carry = 0, idx;
for (idx = 0; idx < MAX_DIGITS; idx++)
Result[idx] = 0;
for (idx = MAX_DIGITS - 1; idx >= 0; idx--)
{
tmp = Op1[idx] + Op2[idx] + carry;
Result[idx] = tmp % 10;
carry = tmp / 10;
}
// when we finished, if we still had a carry out, there was an overflow.
// so if carry is 0, all is well.
return (carry == 0);
}
string BigNumToString(const int Number[])
{
int idx = 0;
string result;
char ch;
while (idx < MAX_DIGITS && Number[idx] == 0)
idx++;
if (idx == MAX_DIGITS) // number was 0
return "0";
// otherwise idx now points at 1st nonzero digit
do
{
// a hardware-portable way to convert from ints to
// characters. The conversion from chars back to ints is
// obviously similar.
switch(Number[idx])
{
case 0: ch = '0'; break;
case 1: ch = '1'; break;
case 2: ch = '2'; break;
case 3: ch = '3'; break;
case 4: ch = '4'; break;
case 5: ch = '5'; break;
case 6: ch = '6'; break;
case 7: ch = '7'; break;
case 8: ch = '8'; break;
case 9: ch = '9'; break;
// this case should never execute
default:
cerr << "Problem in BigNumToString(): Bad value " << Number[idx]
<< " in Number array at idx = " << idx << endl;
ch = 'X'; break;
}
result += ch;
idx++;
} while (idx < MAX_DIGITS);
return result;
}