Jump to content

Welcome to Geeks to Go - Register now for FREE

Need help with your computer or device? Want to learn new tech skills? You're in the right place!
Geeks to Go is a friendly community of tech experts who can solve any problem you have. Just create a free account and post your question. Our volunteers will reply quickly and guide you through the steps. Don't let tech troubles stop you. Join Geeks to Go now and get the support you need!

How it Works Create Account
Photo

Floating Point Exception for Roman Numeral Calc


  • Please log in to reply

#1
SpyD3R

SpyD3R

    New Member

  • Member
  • Pip
  • 1 posts
Hi, I've been just about everywhere on the web, and no one can answer my question. I am designing a Roman Numeral Calculator that will read data from a separate input file using unix redirection, such as ./a.out < data. The main thing that I cannot figure out for my life is the fact that I am getting a floating point error in my code when simply i do not use any sort of decimal that I can see.

Here are the requirements and the assumptions:
read and display the original expression
convert each Roman numeral to its Arabic equivalent
compute the result
display the expression with Arabic numbers
display the result as an Arabic number

Assumptions
All data will be read from a data file via Linux redirection.
All expressions in the data file will be valid (valid operators and Roman numerals).
The Roman numerals and operator in each expression may be separated by 0 or more blanks.
Each line in the data file will be terminated by a linefeed (endl).

This is my test data:
I+XIX
XXIII / V
CCCL +MMI
XIV- XXXV
VI * IX

And finally, this is my code:
#include <iostream>
#include <iomanip>
using namespace std;

void stringToDecimal(char expression[], int &deciRes,
					 const int d[], const char r[]);

void  performOperation(int, int, char, int &);

bool checkForErrors(int, int, char, int);

void decimalToString(int, char romRes[], const int d[], const char r[]);

void outputEquation(char e1[], char e2[], int exDec1, int exDec2,
					char oper, int dResult, char rResult[]);
string e1;
string e2 = "0";
string oper;
int add1;
int sub1;
int mul1;
int div1;
int len1;
int len2;
int pos;
const int  decimal[8] = {0, 1, 5, 10, 50, 100, 500, 1000};
const char roman[8]   = {'O', 'I', 'V', 'X', 'L', 'C', 'D', 'M'};

int main()
{
char   expression1[19],
	   expression2[19],
	   romanResult[19] = {0},
	   operation;

int	decimalEx1 = 0,
	   decimalEx2 = 0,
	   decimalResult;

	bool valid;


	cin >> e1;

	while (cin)
	  {

		add1 = e1.find('+');
		sub1 = e1.find('-');
		mul1 = e1.find('*');
				div1 = e1.find('/');


		if((add1 > -1) || (sub1 > -1) || (mul1 > -1) || (div1 > -1))
		  {
			len1 = e1.length();
			if(add1 > -1)
			  pos = add1;
			else if(sub1 > -1)
			  pos = sub1;
			else if(mul1 > -1)
			  pos = mul1;
			else if(div1 > -1)
			  pos = div1;
			if(len1 > (pos+1))
			  {
				if(add1 > -1)
				  {
					oper = '+';
					e2 = e1.substr((add1+1),(e1.length()-add1));
					e1 = e1.substr(0,(e1.length()-(e1.length()-(add1))));
				  }
				else if(sub1 > -1)
				  {
					oper = '-';
					e2 = e1.substr((sub1+1),(e1.length()-sub1));
					e1 = e1.substr(0,(e1.length()-(e1.length()-(sub1))));
				  }
				else if(mul1 > -1)
				  {
					oper = '*';
					e2 = e1.substr((mul1+1),(e1.length()-mul1));
					e1 = e1.substr(0,(e1.length()-(e1.length()-(mul1))));
				  }
				else if(div1 > -1)
				  {
					oper = '/';
					e2 = e1.substr((div1+1),(e1.length()-div1));
					e1 = e1.substr(0,(e1.length()-(e1.length()-(div1))));
				  }
			  }
			else
			  {
				e1 = e1.substr(0, (len1-1));
				if(add1 > -1)
				  oper = '+';
				else if(sub1 > -1)
				  oper = '-';
				else if(mul1 > -1)
				  oper = '*';
				else if(mul1 > -1)
				  oper = '*';
				else if(div1 > -1)
				  oper = '/';

			  }
		  }


		else
		  cin >> oper;

		len2 = oper.length();
		if(len2 != 1)
		  {
			e2 =  oper.substr(1, (len2-1));
			oper = oper.substr(0, 1);
		  }
		else if((len2 == 1) && (e2 == "0"))
		  {
			cin >> e2;
		  }

		valid = false;

		stringToDecimal(expression1, decimalEx1, decimal, roman);
	   stringToDecimal(expression2, decimalEx2, decimal, roman);

		performOperation(decimalEx1, decimalEx2, operation, decimalResult);

		valid = checkForErrors(decimalEx1, decimalEx2, operation, decimalResult);

		if (valid == true)
		  {
			decimalToString(decimalResult, romanResult, decimal, roman);

			outputEquation(expression1, expression2, decimalEx1, decimalEx2,
						   operation, decimalResult, romanResult);
		  }


	  }
	cout << "Quitting!!!" << endl;

	return 0;
}






void stringToDecimal(char expression[], int &deciRes,
					 const int decimal[], const char roman[])
{
  int i, n, j;

  n = strlen(expression);
  deciRes = 0;

  for(i=0; i < n; i++)
	{
	  for(j=1; j < 8; j++)
		{
		  if(expression[i] == roman[j])
			deciRes += decimal[j];
		}
	}

}

void performOperation(int e1, int e2, char oper, int &deciRes)
{
  switch (oper)
	{
	case '+':
	  deciRes = e1 + e2;
	  break;
	case '-':
	  deciRes = e1 - e2;
	  break;
	case '*':
	  deciRes = e1 * e2;
	  break;
	case '/':
	  deciRes = e1 / e2;
	  break;
	default:
	  deciRes = e1 % e2;
	}
}

bool checkForErrors(int deciEx1, int deciEx2, char oper, int deciRes)
{


  if (oper != '+' && oper != '-' && oper != '*' && oper != '/' &&
	  oper != '%')
	{
	  cout << "Error. Invalid operation" << endl;
	  return false;
	}

  else if(((deciEx1 == deciEx2) && oper =='-') || deciRes == 0)
	{
	  cout << "Error. Result can not be zero" << endl;
	  return false;
	}

  else
	return true;
}

void decimalToString(int decAns, char romAns[], const int d[], const char r[])
{
  int i, j=0, n, count=0;

  // Reset values in romanResult[]
  n= strlen(romAns); // if taken out, ex2 wont show; length romAns not defined
  for(i=0; i < n; i++)
	romAns[i] = 0;
  // End

  for(i=7; i > 0; i--)
	{
	  if( decAns >= d[i])
		{
		  count = decAns / d[i];
		  decAns = decAns - (count * d[i]);

		  while (count != 0)
			{
			  romAns[j] = r[i];
			  j++;
			  count--;
			}
		}
	}
}

void outputEquation(char e1[], char e2[], int exDec1, int exDec2, char oper,
					int dResult, char rResult[])
{
  cout << e1 << " " << oper << " " << e2
	   << " " << " = " << " " << exDec1 << " " << oper << " " << exDec2 << " " << "=" << " " << dResult
	   << " (" << rResult << ") " << endl;

  • 0

Advertisements


#2
darth_ash

darth_ash

    Member 1K

  • Member
  • PipPipPipPip
  • 1,382 posts
Hi SpyD3R,
In your code, on the step where performOperation is called, you are passing the char operation, but I dont see it being intialized\assingned anywhere before it, that is why the default case is chosen always in the performOperation's switch case. Throughout your code you have used the global oper but it looses its scope in the performOperation defination.

Edited by darth_ash, 14 November 2005 - 04:18 AM.

  • 0






Similar Topics

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

As Featured On:

Microsoft Yahoo BBC MSN PC Magazine Washington Post HP