Thread: setting the values of bits

  1. #1
    Registered User
    Join Date
    Nov 2005
    Posts
    137

    setting the values of bits

    say I have two chars and I want to mix up some of the bits in the chars. How exactly do I do this?

    For example if I had:
    Code:
    1110 0101
    0011 1101
    and I wanted to switch the first bits of the chars to get:
    Code:
    0110 0101
    1011 1101
    How would I code that?

    I know there is something that I'm forgetting and when someone tells me I'll kick myself, but right now I think I'm making this way harder than it is. Thank you.

  2. #2
    i dont know Vicious's Avatar
    Join Date
    May 2002
    Posts
    1,200
    You could use bitwise OR

    Code:
    int flag = 0x80; // 1000 0000
    int value = 8; // 0000 1000
    
    value = value | flag; 
    // value == 1000 1000
    What is C++?

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    There's the bitwise logical operators that you can use for such games. But none of them allow you to switch individual bits of two patterns - that requires a more complicated expression.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    i dont know Vicious's Avatar
    Join Date
    May 2002
    Posts
    1,200
    Oh, wow I see waht you're asking now. Sorry about that.

    You could do something similar thoguh. If you just wanted the "first" bit then you could test it with and.

    Code:
    unsigned char byte1 = 0x08; // 0000 1000
    unsigned char byte2 = 0x80; // 1000 0000
    
    // if first bit is 1 make a flag with that bit as 1 also or else 0
    unsigned char byte1_flag = (byte1 & 0x80) ? 0x80 : 0x00;
    unsigned char byte2_flag = (byte2 & 0x80) ? 0x80 : 0x00;
    
    // "swap" the bits
    byte1 |= byte2_flag;
    byte2 |= byte1_flag;
    I think something like that would work. I just typed it in the quick reply so I haven't tested it.

    [edit]
    Heh, apparently I forget my logic. The byte2 "swap" will be 1 OR 0 and will leave it as 1 not change to 0. Shouldn't require too much change though.
    Last edited by Vicious; 04-11-2008 at 02:13 PM.
    What is C++?

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Code:
    if(v1 & 0x80 ^ v2 & 0x80)
    {
        v1 ^= 0x80;
        v2 ^= 0x80;
    }

  6. #6
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Do you mean setting arbitrary bits?

    Code:
    #include <iostream>
    
    void setBit(int &input, int bit)
    {
       input |= 1 << bit;   // OR in 1 moved over bit times
    }
    
    // conversely
    void unsetBit(int &input, int bit)
    {
      input &= ~(1 << bit);  // heavy on the syntax here. This just means
                                         // keep every bit except for 1 moved over bit times
    }
    
    // usage:
    int main(void)
    {
      int x = 0x80;
      setBit(x, 3);
      unsetBit(x, 8);
      std::cout << x;
      return 0;
    }
    Is that what you meant?

  7. #7
    Registered User
    Join Date
    Nov 2005
    Posts
    137
    master I think that is what I want. I'm trying to figure out the fastest way to create a matrix like block and shift the bits around.

    I want to use a block of 8 bytes. I want to set the first byte to the 1st bit of the 1st byte to the 1st byte of the second byte and then the 2nd bit of the 1st byte to the 2nd bit of the 2nd byte... then the 2nd byte I want to set the 1st bit of 2nd byte to the 1st bit of the 2nd bit then the 2nd bit of the 2nd byte to the 2nd bit of the 3rd byte... etc

    I created this loop:
    Code:
         for (i = 0; i < 8; i++)
         {
             for (int j = 0; j < 8; j++)
             {
                 block[i] |= str[(j + i)%8] & (2 << (7 - j));
             }
         }
    But the result seems to be pretty far from what I want. I'm obviously doing something wrong, but I can't find it. Can someone help. Thank you.

  8. #8
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Cool. Well 8 bytes is 64-bits, right? So instead of messing with arrays why not just use a single long long, which is 8 bytes.

  9. #9
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Example
    Code:
    void setMatrixBit(long long &input, int x, int y)
    {
      input |= 1 << (x + (y * 8));
    }
    [edit] I may as well put an unset too
    Code:
    void unsetMatrixBit(long long &input, int x, int y)
    {
      input &= ~(1 << (x + (y * 8));
    }
    Not to be too scary with optimizations, but (x + (y << 3)) would yield a slightly faster yet identical result. x and y denote where in the matrix you are trying to set a bit (my code assumes an 8 x 8 matrix.[/edit]
    Last edited by master5001; 04-11-2008 at 03:26 PM.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    but (x + (y << 3)) would yield a slightly faster yet identical result
    That's assuming your compiler is so stupid that it doesn't do that anyway. Very unlikely.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    How dare you judge my compiler so harshley! Seriously though, true dat. Not to mention the fact I also got waaaaaay ahead of myself and just assumed your matrix is 8x8. Obviously you can change the 8 to whatever the width of your array may be.

  12. #12
    Hardware Engineer
    Join Date
    Sep 2001
    Posts
    1,398
    yahn,

    Take a look at the Bitwise Operation FAQ

    You may have noticed that some posters have used hexadecimal (i.e. 0x80) in their examples/replies.We usually use hex when doing bit manipulation.

    You can't directly* use binary in C/C++, and this makes it very difficult for beginners, because you can't tell that you've changed bit 7** by looking at the decimal values... you have to do some calculations***. (Most of the time, wouldn't want to use binary directly, because binary numbers can be difficult to read or write, especially when you get beyond 16 bits!)

    Converting between hex and binary is much easier than converting between decimal and binary.


    It takes a bit of study and practice if you are not used to working with binary and/or hex, but you can learn to convert numbers (of any size) in your head. This is because each nybble (4-bits) converts exactly to one hex-digit. Once you memorize 16 conversions (0-F), you can do binary to hex conversions (and vice-versa) without any calculations!

    In your example, only the high-nybble is affected by changing bit 7. Notice that "5" remains "5" and the "D" remains "D".


    1110 0101 = 229 decimal = E5 hex
    0110 0101 binary = 101 decimal = 65 hex

    0011 1101 = 61 decimal = 3D hex
    1011 1101 binary = 189 decimal = BD hex

    Every time you see 0101, it converts to 5 hex, etc... If you know that 1110 0101 = E5 hex, then you know that 0101 1110 = 5E hex.... Much easier than decimal!


    * Decimal, hex and octal are included in cin and cout, and you can directly use these "bases" in your code. Binary is not included in cin and cout, and you cannot use it directly in your code source. (C++ does include the <bitset> container, which makes it fairly easy to display numbers in binary.)

    ** The bits (in a byte) are numbered 0 through 7, where bit-0 is the least significant bit.

    *** The calculator included with Windows can do binary, octal, decimal, and hex conversions if you click on Scientific.

  13. #13
    Registered User
    Join Date
    Nov 2005
    Posts
    137
    I see how the long long would be much more efficient, but I don't really see how it works. Also I don't see what I'm doing wrong in the loop.

    str[(j + i)%8] seems like it should be getting the correct char in the array and (1 << (7 - j)) seems like it should be shifting to the right place but I'm thinking that I may need to add another shift to the end because it seems like it might only work for the first byte.

    What exactly is wrong with the loop?

  14. #14
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  15. #15
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Well I am definitely going to need a little bigger snippet of code to help you fix your loop. Since given what you posted I can only guess as to what the result is supposed to be doing. So yahn go ahead and either better explain what the loop is supposed to do, or just give me the whole function.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 05-28-2009, 01:28 PM
  2. Replies: 1
    Last Post: 12-30-2007, 10:08 AM
  3. Help counting number of bits set in an integer
    By JayDiddums10 in forum C Programming
    Replies: 5
    Last Post: 12-07-2006, 03:21 PM
  4. adding ASCII values
    By watshamacalit in forum C Programming
    Replies: 1
    Last Post: 12-26-2002, 07:16 PM
  5. How to read in empty values into array from input file
    By wpr101 in forum C++ Programming
    Replies: 5
    Last Post: 11-28-2002, 10:59 PM