bitwise operators

This is a discussion on bitwise operators within the C++ Programming forums, part of the General Programming Boards category; Can any one explain why we use bitwise operators? Demonstrate it with a good and easy example? A tutorial would ...

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    164

    bitwise operators

    Can any one explain why we use bitwise operators? Demonstrate it with a good and easy example?

    A tutorial would helpful and really appreciated, if possible. Because I think I still didn't got them right

    Thanks
    Last edited by manzoor; 08-18-2008 at 08:25 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,161
    One reason for the use of bitwise operators is efficiency, e.g., it is faster to use bitwise and to check if a number is odd or even than it is to use modulo. Likewise, it is faster to shift a number left or right by one than to multiply or divide it by two, respectively. However, it is easy for compilers to identify and make such substitutions, so these days such manual optimisations are unnecessary.

    Another reason would be to use up as little space as possible to pack a set of boolean values (but again, these days we have the comparative luxury of space). So, say an int has 32 bits, then you can use all 32 bits as 32 boolean flags by using bitwise to check the bits and bitwise or to set them (i.e., bitmasking).

    For a demonstration of the use of bitwise operators, check the tutorial on Bitwise Operators in C and C++.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The other time where bitwise operators are almost unavoidable is when working with hardware. Hardware registers are "expensive" [1], so registers often have more than one component at the same address. This means, that to get the correct value to or from a register, a number of bitwise operators is often necessary. For example, a graphics processor may have something like this in it:
    Code:
       registers->VertHorSize = (VertSize << VHS_VertSizeShift) | (HorSize << VHS_HorSizeShift);
    Libraries that have many options for a function (again, graphics comes to mind) often use one parameter with several portons, e.g.
    Code:
       font.flags = FF_BOLD | FF_UNDERLINE;
    [1] It doesn't cost money as such, but adding more registers makes the decoder for the register more complex, which means that it takes up more space on the chip, which makes the chip more expensive.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    Nov 2007
    Posts
    164
    Well, matsp your examples are a little bit abstract for me I still couldn't grasp how they work, could you, if possible, give an easy example

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,161
    Ah yes, an example that I forgot to mention would be the I/O stream mode flags when opening a file, e.g.,
    Code:
    // Open the file in binary mode and for appending.
    std::ofstream out("example.txt", std::ios::binary | std::ios::app);
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by manzoor View Post
    Well, matsp your examples are a little bit abstract for me I still couldn't grasp how they work, could you, if possible, give an easy example
    What would you like an easy example of?

    The basis of my two examples is that there are constants defined somewhere, such as this:
    Code:
    const unsigned int VHS_VertSizeShift =16;
    const unsigned int VHS_HorSizeShift = 0;
    Further, we would have a set of hardware registers defined something like this:
    Code:
    struct HWregisters
    {
        ...
        UINT32 VertHorSize;
        ...
    };
    
    HWregisters *registers = (HWRegisters *)0x12340000;  // Where the HW registers live in the memory space.
    A function may then look like this:
    Code:
    void SetVideoSize(int vertSize, int horSize)
    {
         registers->VertHorSize = (vertSize << VHS_VertSizeShift) | (horSize << VHS_HorSizeShift);
    }
    So, when we write the 32-bit value for video size, the vertical size is shifted 16 bits, and horizontal size is shifted 0 bits (so no shift, compiler will optimize that away, but it makes it look neat and tidy and you know that it wasn't "forgotten" when reading the code).


    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    839
    one place i used the XOR (^) operator is for valves. they come in lots of different flavors, but the aspect germane to this topic is whether they are normally open or normally closed. this reverses the energization states the relay must be in to put the valve in a given state. (i.e. it reverses the meaning of 1 and 0)

    i keep a bool NO which is true if the valve is normally open and false otherwise.

    *edit* code posted below
    Last edited by m37h0d; 08-18-2008 at 11:07 AM.

  8. #8
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    839
    they're also useful in doing operations on color hex codes, like so:

    Code:
    int color;
    
    unsigned char r;
    unsigned char g;
    unsigned char b;
    
    color = r+(g<<8)+(b<<16);
    Last edited by m37h0d; 08-18-2008 at 10:56 AM.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    valve::close()
    {
        setState(NO^0);
    }
    Seeing as it seems like you are trying to do the opposite of open, I expect:
    Code:
    valve::close()
    {
        setState(NO^1);
    }
    Edit, and if you write (stupidly) code like this:
    Code:
    valve v;
    
    v.open();
    v.close();
    ... 
    v.close();
    The second close will actually make the valve "open", again.

    A better solution would be:
    Code:
    state |= 1;     // Open: set bit. 
    state &= ~1;  // Close: Celar "bit" worth one
    --
    Mats
    Last edited by matsp; 08-18-2008 at 11:01 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    839
    it's NO^0.

    1^0 = 1. which if NO=true, is the closed state.

    should've just c&p'd the code rather than rattling off something i suppose.
    Last edited by m37h0d; 08-18-2008 at 11:06 AM.

  11. #11
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    839
    actually, what i have is:
    Code:
    void valve::open()
    {
            setState(!NO&1);
    }
    
    void valve::close()
    {
            setState(NO^0);
    }
    i did this quite a while ago. i am somewhat puzzled by the !NO&1. the logic is correct, but i am not sure why NO^1 might have been problematic, or if i was just out to lunch that day...

  12. #12
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    839
    Quote Originally Posted by matsp View Post
    Code:
    valve::close()
    {
        setState(NO^0);
    }
    Seeing as it seems like you are trying to do the opposite of open, I expect:
    Code:
    valve::close()
    {
        setState(NO^1);
    }
    Edit, and if you write (stupidly) code like this:
    Code:
    valve v;
    
    v.open();
    v.close();
    ... 
    v.close();
    The second close will actually make the valve "open", again.

    A better solution would be:
    Code:
    state |= 1;     // Open: set bit. 
    state &= ~1;  // Close: Celar "bit" worth one
    --
    Mats
    no it doesn't it sends a second 1 or 0 to the IO.

    NO means "normally open" i.e. the valve is "fail to open". i should have specified that it is const bool. it doesn't track the current state, it tells me whether the relationship between open/closed & 1/0 is reversed or not.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    In summary, you use bitwise operations mostly when you have multiple entities combined to a single addressable object, or a single entity that has several parts.
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bitwise operators
    By gnewfenix in forum C Programming
    Replies: 2
    Last Post: 05-16-2009, 09:43 PM
  2. Bitwise Operators
    By rrc55 in forum C Programming
    Replies: 6
    Last Post: 04-30-2009, 12:37 PM
  3. Palindromes and Bitwise operators
    By Dr Tornillo in forum C Programming
    Replies: 8
    Last Post: 08-02-2007, 03:31 PM
  4. bitwise and arithmetic Operators
    By Whiteghost in forum C Programming
    Replies: 4
    Last Post: 12-28-2006, 02:13 PM
  5. Bitwise Operators, Help!!
    By Mini__C in forum C Programming
    Replies: 6
    Last Post: 07-14-2004, 05:20 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21