Solved

Binary Math With Strings

Posted on 2008-10-24
9
816 Views
Last Modified: 2013-11-27
Hey, I'm trying to make a program that will add, subtract, multiply or divide two binary numbers entered by the user. I want each operation to be in a string. I'm also executing this through a switch statement, I'll show what I have so far.  If there's an easier way of doing what I'm doing, please let me know.

First question, how do I get the switch statement to loop? I mean, after a menu item is selected, it plays out and ends. I would like the menu to come back up after each successful use of the menu.

Second question, how would I go about doing any other operations besides addition? Would it be setup in the same fashion?

If anyone sees something that can be cleaned up or simplified in my code please let me know.


#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <string>
using namespace std;
 
/* ADDITION CODE */
 
	string DtoB (int Decimal); // Convert Decimal to Binary
	void BaseGen(int Base[], int Size); // load the base value of binary number
	int BtoD(string Binary); // convert Binary to decimal
	string AddBin(string Str1, string Str2); // add two binary number
	string Str1, Str2; // Declare Str1 and Str2
	string Sum ;	// Sum will hold the returned total	
 
	string DtoB (int Decimal)
	{
		string Bin ="00000000"; // declare a model binary number
		int Base[8];
		BaseGen(Base,8);// to load the base values
		int Index=7;
		while (Index>=0)
			{
			if (Decimal>=Base[Index])
				{
				Decimal=Decimal-Base[Index];
				Bin[Bin.size()-1-Index]='1';
				}
			Index=Index-1;// reduce the Index
			}
 
		return Bin;
	}
 
	void BaseGen(int Base[], int Size)
	{
		Base[0]=1;		// the first element is always 1
		int Index=1;	// start with the second value
		while(Index<Size)	// must load all Base elements
			{
			Base[Index]=Base[Index-1]*2;	// left = right *2
			Index=Index+1;		// Bump the Index  
			}
		return ;
	}
 
	int BtoD(string Binary)
	{ 
		unsigned int Index=1;  	//loop control variable 
  		Index=0;		// Initialize to zero
		int Dv=0; 		//Dv is the decimal value for the binary number in Binary
		int Base[8];		//  Base array to store binary base values
		BaseGen(Base,8);			// Load Base
		while(Index<Binary.size()) 		// loop to check all bits
			{
			if (Binary[Index]=='1')  		// if the value is 1
			Dv=Dv+Base[Binary.size()-1-Index];  	// add the corresponding base value to Dv
			Index=Index+1; 		// Bump the loop control variable
			}
		return Dv; 			// Return the decimal value
	}
 
	string AddBin(string Str1, string Str2)
	{
		string Sum="00000000";
		int Int1,Int2, Isum;  // DELCARE INTERGERS TO HOLD CONVERTED VALUE
		Int1=BtoD(Str1); // convert Str1 to decimal
		Int2=BtoD(Str2); // convert Str2 to decimal
		Isum=Int1+Int2; // Calculate the sum of two integer
		Sum=DtoB(Isum);  // convert Isum to binary
		return Sum; // return to caller
	}
 
/* END ADDITION CODE */
 
 
int main()
{
	int Choice;
	
	cout << endl << "\t\tBinary Math" << endl << endl;
	cout << "1. Find the Sum of Two Binary Numbers " << endl;
	cout << "2. Find the Difference of Two Binary Numbers" << endl;
	cout << "3. Find the Product of Two Binary Numbers" << endl;
	cout << "4. Find the Quotient of Two Binary Numbers" << endl;
	cout << "5. Exit" << endl << endl;
	cout << "Enter number 1 - 5 for your Choice: ";
	cin >> Choice;
 
	switch(Choice)
		{
		case 1:
				cout << "\n" << endl;
				cout << "Enter Two Binary Numbers With a Sum Less Than 255" << "\n" << endl;
				cout << "First Number:  ";
				cin >> Str1;
				cout << "Second Number: ";
				cin >> Str2;
				Sum = AddBin(Str1,  Str2);
				cout << "Sum:           " << Sum << endl;
				cout << "\n" << endl;
				system("PAUSE");
				break;
		case 2:
			cout << "2" << endl;
			system("PAUSE");
			break;
		case 3:
			cout << "3" << endl;
			system("PAUSE");
			break;
		case 4:
			cout << "4" << endl;
			system("PAUSE");
			break;
		default:
			return(0);
			break;
		}
 
}

Open in new window

0
Comment
Question by:oceanicblack
  • 4
  • 4
9 Comments
 
LVL 13

Accepted Solution

by:
josgood earned 350 total points
ID: 22801778
A simple way to make it loop is
      for (bool keepOn = true; keepOn; ) {
            cout << endl << "\t\tBinary Math" << endl << endl;
          ...the rest of your code as you have it
        }

and adding a case 5
            case 5:
               keepOn = false;
               break;
0
 

Author Comment

by:oceanicblack
ID: 22801803
Thank you, that actually worked perfectly.

I'm still a little stuck on the math operations though. Could they all use the same BtoD/DtoB conversions around the math that must be done? And for subtraction or division, should I use a swap in the event someone enters a larger second number?

Could someone set me on the right path towards another of these math functions?
0
 
LVL 13

Expert Comment

by:josgood
ID: 22801810
You're welcome.  You earlier asked for simplications/cleanups.  Here is a simpler version of BtoD
   int BtoD(string Binary)
   {
      int Dv=0;             //Dv is the decimal value for the binary number in Binary
      int powerOfTwo = 1;
      string::reverse_iterator it;
      for (it = Binary.rbegin(); it != Binary.rend(); it++) {
         int digit = (*it) - '0';
         Dv += digit * powerOfTwo;
         powerOfTwo *= 2;
      }
      return Dv;                   // Return the decimal value
   }
0
ScreenConnect 6.0 Free Trial

At ScreenConnect, partner feedback doesn't fall on deaf ears. We collected partner suggestions off of their virtual wish list and transformed them into one game-changing release: ScreenConnect 6.0. Explore all of the extras and enhancements for yourself!

 
LVL 13

Expert Comment

by:josgood
ID: 22801813
>>Could they all use the same BtoD/DtoB conversions
I see no reason why not...you're converting the strings to integers, performing the operation, and then converting the result back to a string.

The BtoD should check each (*it) to ensure it is a '0' or '1'.  I didn't put that in.

Swapping for subtraction and division is a good idea -- makes for simpler code.  It might surprise the user, however.  Do you need to support negative numbers?
0
 
LVL 13

Expert Comment

by:josgood
ID: 22801823
I suggest organizing your data input this way
   case 1:
      int num1 = GetNumber();
      int num2 = GetNumber();
      int result = num1 + num2;
      cout << "Sum is " << DtoB(result);
      break;
           
Where GetNumber is
   cout << "Enter a binary number of no more than 5 digits "
   string str;
   cin >> str;
   return BtoD(str)

then your case 2 could be
      int num1 = GetNumber();
      int num2 = GetNumber();
      int result = Max(num1,num2) - Min(num1,num2);
      cout << "Sum is " << DtoB(result);
      break;

Does that make sense?
0
 

Author Comment

by:oceanicblack
ID: 22801825
It doesn't really matter much for the subtraction.  The idea was to find the difference between the two so it wouldn't really be possible to be a negative number.  The swap I'll most likely use for just the division.

As for the BtoD, without the check it actually works better... it seems to be able to add and convert the numbers if they are entered as decimal numbers as well.

Thanks, I should be able to take care of it from here. If not I'll be back.
0
 

Author Comment

by:oceanicblack
ID: 22801830
What would be the code to define GetNumber and where would I put it?
0
 
LVL 16

Expert Comment

by:HooKooDooKu
ID: 22801831
The code snippet below shows a simpler BtoD and DtoB.
The BtoD will handle any size string that has a value that can be held within an int.  You could allow binary numbers upto 32 bits if you used unsigned long rather than int.
The idea behind BtoD is to simply multiply the previous value by 2.  This is equal to doing a bit shift left.  You then add 1 to the value if the next character in the string is a '1'.

The DtoB function could also handle values upto an unsigned long if you start with a string of 32 zeros.  However, for presentation, you might want to to add something that drops leading zeros to handle those cases where small numbers have been keyed.
The idea behind DtoB is to find out if the right most bit is a one or zero by dividing the value by 2 (bit shift right) and multiplying by 2 (bit shift left) and comparing before and after to see if a 1 was dropped.  If you are allowed to use the C bitwise AND operator '&', then all the Value2 and Value3 and bit shifting can be replaced by the alternate DtoB.

Yes DtoB and BtoD can be reused.

Another simplification of the logic would be to place the input of two numbers in a subroutine to avoid all the cin<< cout>> being repeated.

If you don't want to deal with negaitve numbers, then you would want to either swap which number is subtracted from the other, or when you do the math, you could do "C = abs( A - B )", then it doesn't matter which is larger.

On the division, that's sort of up to you if you want to swap.  But legal math would be something like 10/20 = 0 when your dealing with integer math.

An even easier loop would be to initialize your Choise variable with a value of 0, and wrap the input and switch case inside a "while( Choise != 5 )"
int BtoD( string Str )
{
	int rc = 0;
	int Index=0;
	while( Index < Str.size()
	{
		rc = rc * 2;
		if( Str[Index] != '0' )
		{
			rc = rc + 1;
		}
		Index = Index - 1;
	}
	return rc;
}
string DtoB( int Value )
{
	string rc = "00000000";
	int Index=8;
	while( Index > 0 )
	{
		Index = Index - 1;
 
		int Value2 = Value / 2;
		int Value3 = Value2 * 2;
		if( Value != Value2 ) //then the right most digit was NOT a zero
		{
			rc[Index] = '1';
		}
         Value = Value2;
	}
}
 
string DtoB_AlternatePlan( int Value )
{
	string rc = "00000000";
	int Index=8;
	while( Index > 0 )
	{
		Index = Index - 1;
 
		if( Value & 1 ) //then the right most digit was NOT a zero
		{
			rc[Index] = '1';
		}
         Value = Value / 2;
	}
}

Open in new window

0
 

Author Comment

by:oceanicblack
ID: 22801874
josgood, I'm a little confused on your GetNumber method. It looks like it will make the whole thing a lot simpler but I'm just not sure what you're saying to do.
0

Featured Post

Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes a technique for converting RTF (Rich Text Format) data to HTML and provides C++ source that does it all in just a few lines of code. Although RTF is coming to be considered a "legacy" format, it is still in common use... po…
Article by: Nadia
Linear search (searching each index in an array one by one) works almost everywhere but it is not optimal in many cases. Let's assume, we have a book which has 42949672960 pages. We also have a table of contents. Now we want to read the content on p…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question