#include #include 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; }