Thread: Working with Binary Numbers in C++

  1. #1
    Registered User
    Join Date
    Nov 2004
    Posts
    73

    Working with Binary Numbers in C++

    Hi everyone,

    I'm having problems getting a flipped binary number (one where all the 1's of a number become 0's and vice versa) to display correctly. My program converts a value from decimal to binary and then should flip the converted binary number so that all 1's become 0's and 0's become 1's. It is not displaying the flipped number properly. I was wondering how I can get it to be displayed so that 1's become 0's and 0's become 1's. I tried using the stndard tilde symbol for accomplishing this but it didn't work. Now I'm stuck as to why it won't work.

    Here is my code for this program so far:

    Code:
    #include <iostream>
    #include <stdlib.h>
    #include <conio.h>
    #include <string>
    #include <bitset>
    
    using namespace std;
    
    class BitHandler {
    
       private:
          unsigned int value;
    
       public:
          void print();
          long binary(int);
          int binflip(int);
    };
    
    void BitHandler::print() {
       value = 128;
       cout << "Decimal Value: " << value << endl;
       cout << "Binary Value: " << binary(value) << endl;
       cout << "Flipped Value: " << binflip(value) << endl;
    }
    
    long BitHandler::binary(int value) {       // converts to binary
       int rem; 
       long x = 0;
       if (value == 0) {
          return 0;
       }
       rem = value % 2;
       value /= 2;
       x = binary(value) * 10 + rem;
       return x;
    }
    
    int BitHandler::binflip(int value) {        // converts to binary
       int rem; 
       int y;
       long x = 0;
       if (value == 0) {
          return 0;
       }
       rem = value % 2;
       value /= 2;
       x = binary(value) * 10 + rem;
       y = ~x;    // this line should flip the binary number to it's inverse
       return y;
    }
    
    int main() {
       BitHandler bits;
       bits.print();
       getche();
       return 0;
    }
    Any help or suggestions would be greatly appreciated. Thanks.

  2. #2
    Banned
    Join Date
    Jun 2005
    Posts
    594
    ~ flips the binary,


    you could try

    Code:
    #include <bitset>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
      bitset<32> b ( string ( "11111111" ) );
    
      cout<< b <<'\n'
        << static_cast<char> ( b.to_ulong() ) <<'\n'
        << static_cast<int> ( b.to_ulong() ) <<'\n';
      cin.get();
      int one = 1;
      cout << one << endl;
      cout << ~one << endl;
      cin.get();
      return 0;
    }
    information on bitsets bitsets

    PS the above was something prelude helped me with.
    Last edited by ILoveVectors; 07-23-2005 at 05:11 PM.

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Try this.
    Code:
    int BitHandler::binflip(int value) {        // converts to binary
       int rem; 
       long x = 0;
       if (value == 0)
          return 0;
       rem = value % 2;
       value /= 2;
       x = binflip(value) * 10 + !rem;
       return x;
    }

  4. #4
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Well, if you are only doing binary and not other bases, bitshifts can make this considerably easier.
    Code:
    #include<iostream>
    #include<string>
    int main (int argc, char* argv[])
    {
           int n = atoi(argv[1]);
           std::string output;
           do
           {
                    output += n < 0 ? "1" : "0";
                    n <<= 1;       
           } while( n != 0 );
           std::cout << output << std::endl;
           return 0;
    }
    Keeps shifting it to the left, and checks if it's less than 0 (because if it shifts and a 1 goes into the negative flag place).

  5. #5
    Registered User
    Join Date
    Nov 2004
    Posts
    73
    Next thing I want to do is to right circular shift the bits of the inverted (flipped) number so that if it is shifted 2 bits to the right then the binary number 00000111 (decimal 7) would become 11000001 (the last two 1's would wrap around to the beginning on the left side because if was shifted to the right by 2 bits).

    I think there is some kind of mathematical formula I need to implement to accomplish this but I'm not sure which one. Does anyone know?

  6. #6
    aoeuhtns
    Join Date
    Jul 2005
    Posts
    581
    That would be...

    Code:
    unsigned char a = 7;
    a = (a >> 2) | (a << (CHAR_BIT - 2));
    I use CHAR_BIT because that's how many bits are in an unsigned char.

  7. #7
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    The fundamental problem with your algorithm is that you are not converting to binary. It is already stored in binary, and then you are changing the number (it is just printed in decimal).

    For example, the nummber 13 has the binary representation 1101. Now, your algorithm converts 13 to 1101 (decimal) which has the binary representation 1001001101. You have a very similar issue with the bit flipping algorithm.

    Cheers
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  8. #8
    Registered User
    Join Date
    Nov 2004
    Posts
    73

    Re:

    Ok Zach but how can I change that? Do I need to make the values char instead of int or long? I am finding it very confusing as to exactly how you get the values in binary form and with 32 bits displayed which is essentially what I want.

  9. #9
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    I am finding it very confusing as to exactly how you get the values in binary form
    Computers store everything in binary format, so that is what you start with. Then, you can choose what format you want to use to display the binary number: decimal, hex, oct, etc.:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    	int my_num= 25343;
    	
    	cout<<my_num<<endl; //dec is the default
    	
    	cout<<showbase;
    	cout<<hex<<my_num<<endl;
    	cout<<oct<<my_num<<endl;
    
    	return 0;
    }
    The standard template library has a bitset type which can be used for displaying numbers in binary format. The bitset type also has a flip() function. Here is an example:
    Code:
    #include <iostream>
    #include <bitset>
    
    using namespace std;
    
    int main()
    {
    	bitset<32> myBinary(13);
    	cout<<myBinary<<endl;
    
    	myBinary.flip();
    	cout<<myBinary<<endl;
    
    	return 0;
    }
    Last edited by 7stud; 07-24-2005 at 12:04 PM.

  10. #10
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Well, what you really want to get back is a string of some sort, and not a number. So, you either want to get back a std::string (recommended) or a c-style char*, placing a '1' in the string for every corresponding 1-bit in the number, and likewise for 0s.

    I've written up a short example of how I might do it. I don't have too much time right now, so it may seem a little bit of a muddled solution, which could be clearer. Also, I used c-style strings, but I'll be back later, so if you have any questions on how it works, just post them. At any rate, working through what it does might be instructive.

    Cheers

    Code:
    #include <iostream>
    #include <limits>
    
    char* binary(unsigned long x)
    {
       static int size = 
          sizeof(unsigned long) * std::numeric_limits<unsigned char>::digits;
       char* str = new char[size + 1];
    
       for(int j = 0; j != size; ++j)
          str[j] = (x & 1 << (size - j - 1)) ? '1' : '0';
    
       str[size] = '\0';
       return str;
    }
    
    int main( )
    {
       unsigned long x;
    
       std::cout << "Enter a positive integer: ";
       std::cout.flush();
       std::cin >> x;
       
       char* bin = binary(x);
       char* binnot = binary(~x);
       
       std::cout << "binary(x)  = " << bin << std::endl;
       std::cout << "binary(~x) = " << binnot << std::endl;
       
       delete[] bin;
       delete[] binnot;
       
       return 0;
    }
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  11. #11
    Registered User
    Join Date
    Nov 2004
    Posts
    73
    OK I've modified the code so that now the binary conversion and flipping works but now I'm having problems getting the wrapping part for the right circular shift to work.

    In my example, binary: 00000000000000000000000000000111 (decimal 7) after a right circular shift of 2 bits should become 11000000000000000000000000000001 (the last two 1's should be moved to the front of the number on the left side in a wrapping style).

    I thought that putting in value >> 2 (right shift 2 bits) would work and it is partially working but it does not wrap the last two 1's to the front of the number on the left side as it should. The last two 1's just end up lost in memory so I need to modify it so that the last two 1's will wrap around to the beginning of the number on the left side.

    What do I need to change for this to work correctly?

    Here is the code that I have for that:

    Code:
    #include <iostream>
    #include <stdlib.h>
    #include <conio.h>
    #include <string>
    #include <bitset>
    
    using namespace std;
    
    class BitHandler {
    
       private:
          unsigned int value;
    
       public:
          void print();
          char* binary(int);
    };
    
    void BitHandler::print() {
       value = 7;
       cout << "Decimal Value: " << value << endl;
       cout << "Binary Value:  " << binary(value) << endl;
       cout << "Flipped Value: " << binary(~value) << endl;
       cout << "Shifted Value: " << binary(value >> 2) << endl;
    }
    
    char* BitHandler::binary(int value) {       // converts to binary
       static int size = sizeof(unsigned long) * 8;
       char* str = new char[size + 1];
    
       for(int j = 0; j != size; j++) {
          str[j] = (value & 1 << (size - j - 1)) ? '1' : '0';
       }
       str[size] = '\0';
       return str;
    }
    
    int main() {
       BitHandler bits;
       bits.print();
       getche();
       return 0;
    }
    Any advice or suggestions would be greatly appreciated. Thanks.

  12. #12
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    I thought that putting in value >> 2 (right shift 2 bits) would work and it is partially working but it does not wrap the last two 1's to the front of the number on the left side as it should.
    Can you quote any C++ documentation where it says the shift left and shift right operators are supposed to wrap around??
    Last edited by 7stud; 07-24-2005 at 12:31 PM.

  13. #13
    Registered User
    Join Date
    Nov 2004
    Posts
    73
    You're absolutely right 7stud. All that does is shift to the right by the specified number. It does not wrap it around. I'll need to use some kind of other formula then as I suspected all along to get this to work.

  14. #14
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    so I need to modify it so that the last two 1's will wrap around to the beginning of the number on the left side.

    What do I need to change for this to work correctly?
    You could convert the bitset type to a string, and write a function that chops off the string representation of the binary number at a certain point and adds it to the front or back of the remaining substring.

  15. #15
    *this
    Join Date
    Mar 2005
    Posts
    498
    Or if you do this 3 >> 2

    Code:
    char num = 3;
    
    for (int loop = 0; loop < 2; loop++)
    {
       if (num & 1) { num >> 1; num += 0x80; }
       else num >> 1;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reducing rational numbers - code not working properly
    By adrian2009 in forum C Programming
    Replies: 2
    Last Post: 04-17-2009, 07:42 AM
  2. Replies: 0
    Last Post: 11-04-2006, 11:07 AM
  3. Working with Strings and Numbers
    By jamez05 in forum C++ Programming
    Replies: 8
    Last Post: 10-19-2005, 12:39 PM
  4. binary
    By webturtle0 in forum A Brief History of Cprogramming.com
    Replies: 52
    Last Post: 12-05-2002, 02:46 AM
  5. the definition of a mathematical "average" or "mean"
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 12-03-2002, 11:15 AM