Directory:Derek Elder/Programs/ReadBigInt Modified

< Directory:Derek Elder‎ | Programs
Revision as of 22:13, 1 November 2007 by Derek Elder (talk | contribs) (start of page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
#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);
}