Hi,
I'm having a problem wrapping my head around a problem. Here is the problem:
Develop a program that will input a binary string and then, using bitwise operations, do a two's complement on the string and display it. Use UNSIGNED data types for the bit strings.

So far, I have a class that takes a c-string in the constructor and converts that to an integer using atoi() then I set a temporary variable to the ~ (complement) of the variable and add 1. But I don't really know if I'm even doing it right.

I call it like this:
BinaryString convert("00000010");

And it "works" like this:

BinaryString::BinaryString(char* in)
{
	binary=0;
	input=in;
	doConverttoInt();
}

void BinaryString::doConverttoInt()
{
	binary =( unsigned int)atoi(input);
	std::cout << "binary is " << binary << std::endl;
	performComplement();

}

void BinaryString::performComplement()
{
	
	//input
	unsigned int temp;
	temp = ~binary;
	temp+=1;
	std::cout << "complement is " << temp << std::endl;

}

This all just produces garbage, as atoi strips the leading 0's, and temp variable gives me some ridiculously high number.

Clinton Portis commented: I love performing bit-level operations..!! :) +5

Recommended Answers

All 7 Replies

Get number (in binary) and enter into a string:

string binary;

cout << "Enter a binary number: ";
cin >> binary;

Turn a binary number into a real number:

#include<algorithm>
unsigned int number = 0;
int exp = 0;

//I think most people read binary right-to-left
//the conversions are made easier (for me) if we flip it around
reverse(&binary[0], &binary[binary.size()]);

for(int i=0, size=binary.size(); i<size; i++)
{
     if(binary[i] == '1')
     {
          number += pow(2, exp);
     }

     exp = pow(2, exp);
}

unsigned int orig_number = number;

Perform 2's compliment:

number = ~number + 1;

Turn it back into a string:

bool bit = 0;
string twocomp;

for(int i=0, size=binary.size(); i<size; i++)
{
     //Get right-most bit
     bit = number & 1;

     if(bit)
     {
          twocomp += '1';
     }
     else
     {
          twocomp += '0';
     }

     //Shift all bits right one place
     number >>= 1;
}

Display useful information to the user:

//Flip the 'binary' strings back around so people can read it right-to-left
reverse(&binary[0], &binary[binary.size()]);
reverse(&twocomp[0], &twocomp[twocomp.size()]);

cout << "The orignal number entered in binary: " << binary;
cout << "Which is: " << orig_number;
cout << "The 2's compliment is: " << twocomp;
cout << "Which is: " << number;

*The above code is untested, uncompiled, and may contain simple easy to fix errors; it is intended as a suggestion only. If you see a better way to do this, I am always open to suggestions.

Member Avatar for r.stiltskin

You shouldn't be using atoi because atoi assumes that the input string represents a decimal number, e.g. it converts the string "00000010" to the decimal number 10, whereas your binary string "00000010" represents the decimal number 2. You have to write your own conversion function to translate the binary string to its decimal equivalent before you can apply the bitwise 'not'.

First id like to say thanks Clinton.
I had a bunch of issues trying to implement Clinton's code, mainly using the pow() function. So I made my own and everything seems to be "working" up until the point I try to do the integer to binary.

unsigned int BinaryString::power()
{
	unsigned int temp=1;
	std::cout << "power called with exponent " << xp-1;
	//loop through # of times to do exponent
	for(int i=0;i<xp-1;i++)
	{
		temp*=2;
	}
	return temp;
}

void BinaryString::doConverttoInt()
{
	int a=input.size()-1;//first digit right to left
	if(input[a] == '1'){
		number = 0;
	}
	for(int i=a;i>0;i--)//start at right
	{
		xp++;
		if(input[i] == '1')
		{
			//exponent via the position
			number+=power();
		}
		
	}
	orig_number = number;
	performComplement();
}


void BinaryString::inttoBinary()
{
	bool bit = 0;
	int a=input.size();
	for(int i=a; i>0; i--)
	{
		//get right-most bit
		bit = number & 1;
		if(bit)
			twocomp+= '1';
		else
			twocomp+='0';
		number >>= 1;
	}

}

When the constructor is passed this: 11011011
the result is: original # in binary 11011011
which is 91
the 2's compliment is: 10100101
which is: 16777215

I think the compliment is just flipped as in left to right rather than right to left. Any thoughts? It's gotta be something simple.

EDIT: Yeah that binary number isn't even 91 so my function doesn't even work right anyway. =\ More help++ ?

Thanks in advance.

I'm not totally convinced that your power() function is working properly....

If you weren't familiar with the pow() function, it's derived from <cmath>

Give it a try and see if that works any better for ye'.


And yes, there is also a significant issue here with how the binary number is entered by the user.

If the user elects to read the binary number 'right-to-left', as the user types it in, it will appear 'left-to-right' on the screen...

If the user decides to make the screen entry look 'right-to-left'... the user would actually have to input the numbers 'left-to-right.'

I didn't write all this to purposely confuse you. I've been taught to read binary both ways. I'm not sure if there is a set standard.

After you are done with this program, I would recommend providing thorough prompts to the user on how you want your data entered. Some error checking could also be done as well; you could provide the user the base 10 numerical version of the number and ask for verification if this is correct, for example.


In this code below, 'number' is affected by all the bit shifting. I probably should have saved it so I could use it later for console display:

output:
bool bit = 0;
string twocomp;
//save this before messing it up!
unsigned int temp = number;

for(int i=0, size=binary.size(); i<size; i++)
{
     //Get right-most bit
     bit = number & 1;

     if(bit)
     {
          twocomp += '1';
     }
     else
     {
          twocomp += '0';
     }

     //Shift all bits right one place
     number >>= 1;
}

EDIT: Fixed my power function and the binaries are correct with the number. I guess all I'm asking now is how to get the right bit first instead of left side. I'm not sure how the binary operators work exactly.

void BinaryString::inttoBinary()
{
	bool bit = 0;
	int a=input.size();
	for(int i=a; i>0; i--)
	{
		//get right-most bit
		bit = binary & 1;
		if(bit)
			twocomp+= '1';
		else
			twocomp+='0';
		binary >>= 1;
	}

}

Yes, I know my power function isn't working properly, it seemed to be working for 3 - 00000011 and I tested another number and that worked so I figured I got it. the pow() in cmath yes I looked it up and implemented it all the way doesnt take an unsigned int, it only takes floats and doubles (and their long counterparts) that's why i couldn't figure it out. Plus I couldn't figure out what those reverse functions did because they threw errors, and yes I did include algorithm.

--
So what you're saying is I had to specifically ENTER the binary backwards (right to left) from the beginning? I was just trying to modify what your idea was and make it go from right to left hence starting at position 7 instead of 0.
e.g. int a=input.size()-1;

Also I'm not going to implement any functionality for the user to input the way they want it to read (left->right or left<-right) because I just don't have to do that and I don't have a lot of time left :P.

But that's not anyone's fault but mine, thanks for all the help Clinton.

You seem obviously confused and not really sure about what's going on. So I'll make life simple for you.

For now, it's ok to assume correct user input.

With that out of the way, now you can focus on the program.

It's ok to use the pow() function from cmath.

Just because the pow() function does not take unsigned arguments has no effect on the rest of the program whatsoever.

Consistent correct math will out weigh any negative consequences you can think of.

The only data types that we absolutely need to have 'unsigned' are those that we wish to perform bit level operations.

With intel x86 architecture, binary numbers are read 'right to left' (ok so I just answered my own question)

Therefore, all the code I have supplied you thus far has been correct.

Member Avatar for r.stiltskin

If the user elects to read the binary number 'right-to-left', as the user types it in, it will appear 'left-to-right' on the screen...

If the user decides to make the screen entry look 'right-to-left'... the user would actually have to input the numbers 'left-to-right.'

I didn't write all this to purposely confuse you. I've been taught to read binary both ways. I'm not sure if there is a set standard.

This seems unnecessarily confusing. You can *read* numbers by whatever technique you like, as long as we all agree that numbers (whether binary, decimal, octal, or whatever) are *always* written with the highest order digit on the left.

For what it's worth, it is very easy to convert a binary string to an int without all those calls to reverse() and pow():

unsigned int binstring2dec (string binstring) {
  unsigned int val = 0;
  for (int i = 0; i < binstring.length(); ++i) {
    val = 2 * val + binstring[i] - 48;
  }
  return val;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.