Thread: Good examples/uses of bitwise operations?

  1. #1
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665

    Good examples/uses of bitwise operations?

    I'ma just go ahead and make the assumption that bitwise operations are the fastest. Also, assume non-embedded programming because I saw a post about bitwise stuff breaking down under certain circumstances.

    So, does anyone have any good uses or examples of bitwise operations that replaced slower conventions that only a young and inexperienced programmer would use?

    Like, they replaced a complicated check for an if-statement with bitwise operations.

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Radix sorting, Some Merge and hybrid sorts, some Sudoku solvers and checkers, Duff's device (go to Wiki for more info on that), Chess programs that use bitboards (many do). Working with pixels in a graphics program. Compression programs, encryption programs.

    I'm getting some help de-bugging one for C, right now (from C++). It generates random data, using bit operations. I'll post it when it's working.

  3. #3
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    The standard ones:
    Code:
    x = x<<1; /* shortcut for *2 (and *4 etc..)  */
    x = x>>1; /* shortcut for /2 (and /2 etc..) */
    if (x & 1) { /* x is odd */ }
    else { /* x is even */ }
    It's also quite common (and useful) to use individual bits as options or boolean values, such as in a flag variable:
    Code:
    enum network_flags {
      FL_SSL = 0x01,
      FL_NONBLOCKING = 0x02,
      FL_AUTORECONNECT = 0x04,
      /* ... 0x08, 0x10, 0x20, etc.. */
    } flags;
    ...
    ...
    if (flags & FL_AUTORECONNECT) { /* handle reconnect .. etc */ }

  4. #4
    11DE784A SirPrattlepod's Avatar
    Join Date
    Aug 2013
    Posts
    485
    Set value to 0, optimised version: x ^= x;

  5. #5
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    a classic way to swap values between two variables without using a temp variable:

    a ^= b;
    b ^= a;
    a ^= b;

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I don't recall having used it myself and there isn't really the bitwise aspect to it, but in a situation where you want to write if (foo() && bar()) such that both functions will always be called, changing the && to & may be an applicable solution.

    Quote Originally Posted by MutantJohn
    I'ma just go ahead and make the assumption that bitwise operations are the fastest.
    Note that a compiler may optimise code that does not use bitwise operations to use bitwise operations if they are common cases such that the change should result in faster code. Things like multiplying/dividing by a constant that is a power of two to become a bitwise shift, or changing n % 2 to n & 1 comes to mind. Likewise, unless you intend obfuscated code, there would be no advantage in using SirPrattlepod's example over a direct assignment of 0, even if somehow the translation without optimisation would have resulted in faster code: assignment of 0 should be so common that any sane compiler author would make the compiler do it even without any optimisations turned on.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    My understanding is that bit-wise operations are quite fast because they can be done in parallel - if the compiler and system allow it, and I don't know of any late model desktop or server cpu (AMD or Intel or ARM, at least), that doesn't support it.

    The source of that was a professor who did parallel testing for Intel at a Uni, so I trust it.

  8. #8
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    I intend to only write obfuscated code.

    I like the suggestions so far though

  9. #9
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    It should be made clear that none of the above tricks will gain you anything. It's best to write clear, idiomatic code and let the compiler perform the optimizations since they may be different for different platforms.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  10. #10
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    But they look so smart! I wanna look smart!

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Generally, the stuff that Adak mentioned are not mere tricks but legitimate techniques. nonpuz's example of bitwise flags is a well known idiom that is used in the C standard library.

    I'd say that my example is something of a trick since it runs the risk that a reader may mistake your intention, but then no compiler can "optimise" the && to an & since it could change the result of the code (and isn't an optimisation anyway).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    I should have specified which ones I would call useless tricks:
    Code:
    x <<= 1;  // if what you mean is x *= 2;
    
    x ^= x;   // instead of x = 0;
    
    a ^= b;
    b ^= a;
    a ^= b;
    Using & as a non-short-circuiting && is also a trick, since you can just write:
    Code:
    int fooval = foo();
    if (bar() && fooval)
    and the compiler can optimize fooval away.

    The other mentioned techniques are obviously valid and useful.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  13. #13
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by rcgldr View Post
    a classic way to swap values between two variables without using a temp variable:

    a ^= b;
    b ^= a;
    a ^= b;
    Yeh and then you fall on your face when at some time the a == b initially...
    For me - this is classic example how NOT to swap variables
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  14. #14
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by rcgldr View Post
    a classic way to swap values between two variables without using a temp variable:

    a ^= b;
    b ^= a;
    a ^= b;
    Quote Originally Posted by vart View Post
    ... a == b initially
    It still works.

    Clear the least significant bit of x:

    Code:
        x = x & (x-1);

  15. #15
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You can use bit logic like this to create any pattern of digits you want. Here rcgldr uses unsigned int64 data types, to work on.

    vData[] is an array of 100 these unsigned int64's (typedef'd to use the handle of UI64)

    rand() returns a smaller int, so it has to be cast to UI64's size.


    Code:
    	for(j =	0; j < 100; j++){
    		i  = (((UI64)((rand()>>4) &	0xff))<< 0);
    		i += (((UI64)((rand()>>4) &	0xff))<< 8);
    		i += (((UI64)((rand()>>4) &	0xff))<<16);
    		i += (((UI64)((rand()>>4) &	0xff))<<24);
    		i += (((UI64)((rand()>>4) &	0xff))<<32);
    		i += (((UI64)((rand()>>4) &	0xff))<<40);
    		i += (((UI64)((rand()>>4) &	0xff))<<48);
    		i += (((UI64)((rand()>>4) &	0xff))<<56);
    
    		
             vData[j] = i;
    
             if(j<100)
                 printf("j: %llu   i: %llu vData[j]: %llu\n",j,i,vData[j]); 
    
        }
    More bit twiddling:
    http://graphics.stanford.edu/~seander/bithacks.html
    Last edited by Adak; 10-17-2013 at 11:28 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bitwise Operations Help Please!
    By workisnotfun in forum C Programming
    Replies: 2
    Last Post: 11-19-2012, 10:22 AM
  2. Bitwise Operations
    By drkidd22 in forum C Programming
    Replies: 2
    Last Post: 11-12-2009, 11:09 PM
  3. Anyone good with bitwise operations/page detection
    By someprogr in forum C Programming
    Replies: 2
    Last Post: 12-16-2008, 10:33 AM
  4. bitwise operations
    By barneygumble742 in forum C Programming
    Replies: 10
    Last Post: 09-11-2004, 10:33 AM
  5. bitwise operations
    By bukko in forum C Programming
    Replies: 3
    Last Post: 10-06-2001, 06:56 AM