#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
class BigInt
{
friend BigInt operator+(const BigInt& num1, const BigInt& num2);
//Purpose:Operator overloaded, + operator will call AddBigInts.
//Precondition:None.
//Postcondition:The two BigInts have been added together.
friend ostream& operator<<(ostream& os, const BigInt& num);
//Purpose:Operator overloaded, << operator will call PrintToBigInt.
//Precondition:None.
//Postcondition:The BigInt is printed.
friend bool AddBigInts(const BigInt& num1, const BigInt& num2, BigInt& sum);
//Purpose:Add two integers together into a sum.
//Precondition:BigInts num1 and num2 are valid.
//Postcondition:1.Return true if sum is valid.
// 2.Return false if there is overflow.
friend void firstIntegerLarger(const BigInt& largest, const BigInt& smallest, BigInt& sum);
//Purpose:Modularize AddBigInts function to make it more efficent.
//Precondition:BigInts num1 and num2 have been entered and contain good data.
//Postcondition:1.Sum has been populated by good data as long as numDigits <= MAX.
// 2.If there is overflow (numDigits > MAX) it will be indicated in operator+.
public:
static const int MAX = 5;
BigInt();
//Default Constructor
//Purpose:Set numDigits to 0 to indicate an array is not populated.
//Precondition:None.
//Postcondition:Constructor has set numDigits to 0 indicating the array is not populated.
BigInt(const string& goodString);
//Constructor
//Purpose:If num is intitalized in main with a value, the constructor calls StringToBigInt.
//Precondition:None.
//Postcondition:BigInt num has been converted from a string into an array.
bool ReadBigInt(istream& is = cin);
//default stream arg; ReadBigInt() means use "cin".
//Purpose:Read a BigInt, deposit into a string and call StringToBigInt.
//Precondition:None.
//Postcondition:1.Array is populated, data is valid.
// 2.BigInt is too large, loops until an Int is entered that is small enough.
void PrintBigInt(ostream& os = cout) const;
//default stream arg; PrintBigInt() means use "cout".
//Purpose:Print a BigInt in the same way it was entered by reversing the way it was stored into the array.
//Precondition:BigInt num is valid.
//Postcondition:Data is printed on screen matching the way it was entered from the console.
private:
void StringToBigInt(const string& goodString);
//Purpose:Convert from characters to numeric data
//Precondition:Assume "goodString" is perfect.
//Postcondition:goodString is converted into numeric data and entered into an array.
int Digits[MAX];
int numDigits;
};
class OverFlowException
{
public:
BigInt m_num1, m_num2;
char m_op;
OverFlowException(const BigInt& num1,const BigInt& num2, char op)
{
m_num1 = num1;
m_num2 = num2;
m_op = op;
}
};
void main()
{
BigInt num1, num2;//("12345");
bool moreNumbers = true;
char update = ' ';
while(moreNumbers)
{
try
{
num1.ReadBigInt();
num2.ReadBigInt();
cout<<"The BigInt entered is: ";
num1.PrintBigInt();
cout<<"The BigInt entered is: ";
num2.PrintBigInt();
cout<<"The sum is: "<<num1 + num2;
}
catch(OverFlowException ex)
{
cout<<"The sum has caused OVERFLOW"<<endl;
}
cout<<"Do you wish to add more numbers? ";
cin>>update;
cin.ignore(50,'\n');
if(update == 'Y' || update == 'y')
{
moreNumbers = true;
}
else
{
moreNumbers = false;
}
}
cout<<"Program Terminated on request."<<endl;
}
bool BigInt::ReadBigInt(istream& is)
{
int len = 0;
bool tooBig = false;
string inputString = "";
while(!tooBig) //Initialize tooBig, if integer is too big loop until BigInt entered is valid.
{
cout<<"Enter an integer: ";
getline(cin,inputString);
len = (int)inputString.length(); //Length of the string entered into len
if(len > MAX)
{
cout<<"The number you entered is too big, try again!"<<endl;
tooBig = false;
}
else
{
StringToBigInt(inputString);
tooBig = true;
}
}
return true;
}
void BigInt::PrintBigInt(ostream& os) const
{
int counter = numDigits - 1;
for(int i = 0; i < numDigits; i++)
{
cout<<Digits[counter];
counter--;
}
cout<<endl;
}
bool AddBigInts(const BigInt& num1, const BigInt& num2, BigInt& sum)
{
if(num1.numDigits >= num2.numDigits)
{
firstIntegerLarger(num1, num2, sum);
}
else
{
firstIntegerLarger(num2, num1, sum);
}
//If Overflow return false, otherwise return true
if(sum.numDigits > MAX)
{
return false;
}
else
{
return true;
}
}
void firstIntegerLarger(const BigInt& largest, const BigInt& smallest, BigInt& sum)
{
int i;
int remainder = 0;
for(i = 0; i < smallest.numDigits; i++)
{
sum.Digits[i] = largest.Digits[i] + smallest.Digits[i] + remainder;
if(sum.Digits[i] >= 10)
{
sum.Digits[i] = (sum.Digits[i] - 10);
remainder = 1;
}
else
{
remainder = 0;
}
}
for(; i < largest.numDigits; i++)
{
sum.Digits[i] = largest.Digits[i] + remainder;
if(sum.Digits[i] >= 10)
{
sum.Digits[i] = (sum.Digits[i] - 10);
remainder = 1;
}
else
{
remainder = 0;
}
}
if(i == largest.numDigits && remainder == 1)
{
sum.Digits[i] = 1;
sum.numDigits = largest.numDigits + 1;
}
else
{
sum.numDigits = largest.numDigits;
}
}
void BigInt::StringToBigInt(const string& goodString)
{
int counter = 0;
string str = "";
str = goodString;
numDigits = (int)str.length();
char ch = ' ';
for(int i = numDigits-1; i >= 0; i--) //Reverse the string and position of numbers
{
ch = str[i]; //Convert from char to numeric value
Digits[counter] = ch - '0'; //char c = '2';
counter++; //int n = c - '0';
}
}
BigInt operator+(const BigInt& num1, const BigInt& num2)
{
BigInt sum;
if(AddBigInts(num1,num2,sum) == false)
{
OverFlowException ex(num1,num2,'+');
throw ex;
}
else
return sum;
}
ostream& operator<<(ostream& os, const BigInt& num)
{
num.PrintBigInt(os);
return os;
}
BigInt::BigInt()
:numDigits(0)
{}
BigInt::BigInt(const string& goodString)
{
StringToBigInt(goodString);
}