Directory:Derek Elder/Programs/ReadBigInt Modified

MyWikiBiz, Author Your Legacy — Sunday December 22, 2024
Jump to navigationJump to search
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

const int MAX = 50;

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 BigInt operator*(const BigInt& num1, const BigInt& num2);
	//Purpose:Operator overloaded, * operator will call MultBigInts.
	//Precondition:None.
	//Postcondition:The two BigInts have been multiplied 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 bool MultBigInts(const BigInt& num1, const BigInt& num2, BigInt& product);
	//Purpose:Multiply two integers together into a product.
	//Precondition:BigInts num1 and num2 are valid.
	//Postcondition:1.Return true if product 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.
	bool ExtractGoodString(const string& input, string& output);
	//Purpose:To make sure the goodstring is valid.
	//Precondition:StringToBigInt has been called.
	//Postcondition:A valid string is returned.
private:
	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;
	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 product is: "<<num1 * num2;
			cout<<"The sum is: "<<num1 + num2;
		}
		catch(OverFlowException ex)
		{
			cout<<"The sum or product has caused OVERFLOW"<<endl;
		}

		cout<<"Do you wish to continue? ";
		cin>>update;
		cout<<"========================="<<endl;
		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;
	}
}
bool MultBigInts(const BigInt& largest, const BigInt& smallest, BigInt& product)
{
	int i, j, k;
	int remainder;
	BigInt temp, temp2;
	bool flag;

	temp.numDigits = 0;
	temp2.numDigits = 0;
	product.numDigits = 0;

	for(i = 0; i < smallest.numDigits; i++)
	{
		remainder = 0;
		temp2 = product;

		if(temp2.numDigits >= MAX)
			return false;

		for(j = i; j > 0; j--)
		{
			temp.Digits[j - 1] = 0;
		}

		for(k = 0; k < largest.numDigits; k++)
		{
			temp.Digits[k + i] = smallest.Digits[i] * largest.Digits[k] + remainder;

			if(temp.Digits[k + i] >= 10)
			{
				remainder = temp.Digits[k + i] / 10;
				temp.Digits[k + i] = temp.Digits[k + i] % 10;
			}
			else
				remainder = 0;
		}

		if(remainder >= 1)
		{
			temp.Digits[k + i] = remainder;
			k++;
		}

		temp.numDigits = (k + i);
		flag = AddBigInts(temp2,temp,product);
	}
	return flag;
}
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;
}
BigInt operator*(const BigInt& num1, const BigInt& num2)
{
	BigInt product;
	if(MultBigInts(num1,num2,product) == false)
	{
		OverFlowException ex(num1,num2,'*');
		throw ex;
	}
	else
		return product;
}
ostream& operator<<(ostream& os, const BigInt& num)
{
	num.PrintBigInt(os);
	return os;
}
BigInt::BigInt()
:numDigits(0)
{}
BigInt::BigInt(const string& goodString)
{
	StringToBigInt(goodString);
}