Cypras
Cypras

Reputation: 488

Bit Operations, mainly ~

I am currently converting decimal to binary, making sure it is 8 bits. All bit operations work except the ~ (NOT) operations. They come out as a huge integer value. I am not sure why, since the other bit operations work. Here is my code: (The commented out lines are what is not working)

Edit: If I want to get 8 bit binary strings, what do I do? Use unsigned chars? If I change all unsigned ints to unsigned chars then my BinaryToDecimal function produces incorrect binary conversion.

#include <iostream>
#include <string>

using namespace std;

string BinaryToDecimal(unsigned int dec)
{
    string binary   = "";
    float remainder = 0.0f;

    while( dec != 0 )
    {
        remainder = dec % 2;
        dec      /= 2;

        if( remainder == 0 )
            binary.append("0");
        else
            binary.append("1");
    }


    // Reverse binary string
    string ret = string(binary.rbegin(), binary.rend());

    return ret;
}

int main()
{
    unsigned int a = 0;
    unsigned int b = 0;

    cout << "Enter a number to convert to binary: ";
    cin  >> a;
    cout << "Enter a number to convert to binary: ";
    cin  >> b;

    cout << "A = " << BinaryToDecimal(a) << endl;
    cout << "B = " << BinaryToDecimal(b) << endl;

    unsigned int c = a & b;
    unsigned int d = a | b;
    //unsigned int e = ~a;
    //unsigned int f = ~b;
    unsigned int g = a ^ b;
    unsigned int h = a << 2;
    unsigned int i = b >> 3;

    cout << "A & B  = " << BinaryToDecimal(c) << endl;
    cout << "A | B  = " << BinaryToDecimal(d) << endl;
    //cout << "~A     = " << BinaryToDecimal(e) << endl;
    //cout << "~B     = " << BinaryToDecimal(f) << endl;
    cout << "A ^ B  = " << BinaryToDecimal(g) << endl;
    cout << "A << 2 = " << BinaryToDecimal(h) << endl;
    cout << "B >> 3 = " << BinaryToDecimal(i) << endl;
}

Upvotes: 1

Views: 158

Answers (2)

jclin
jclin

Reputation: 2549

You are using an unsigned int for the operations, such that the inversion of small number becomes a large number because of leading 1 starting from the MSB. If you only want the representation is 8 bit only, you should use unsigned char for its storage.
But you cannot change a or b to unsigned char. Otherwise, cin >> a will put the number's ASCII code to a, not a number. For example, your input is 5, it puts 0x35 ('5'), not number 5.

If you don't want to change unsigned int of your code, you can do some minor enhancements

string BinaryToDecimal(unsigned int dec)
{
    string binary   = "";
    float remainder = 0.0f;

    dec &= 0xff;        // only 8 bits you care about
    while( dec != 0 )
    {
        ....

But you are using while( dec !=0 ), which is buggy. If the result is already 0, then the function returns an empty string, not "0000". Instead, you should use a counter to count only for 8 bit.

    for (int i = 0; i < 8; i++ ) {
        if ((dec & 1) != 0)
            binary.append("1");
        else
            binary.append("0");
        dec >>= 1;
    }

Also, using bit wise AND to test the bit is 0 or 1, and shift operation, is better than / and % operators.

Finally, for 8 bit 5 (0000_0101), its inversion is 250 (1111_1010), not 1010.

Upvotes: 0

davmac
davmac

Reputation: 20631

If you perform a binary NOT on a small unsigned integer, you will get a large number as a result, seeing as most of the most significant bits will be set to 1 (the inverse of what they were in the operand).

In this case you're doing ~ 0 which will certainly give you a large number, in fact the largest possible unsigned int, since all bits will be set to 1.

(What result were you expecting?)

Upvotes: 2

Related Questions