Click here to Skip to main content
Licence CPOL
First Posted 20 Dec 2001
Views 120,911
Downloads 640
Bookmarked 41 times

Easier bitwise operations

By | 25 Dec 2001 | Article
A collection of templates that simplify the comprehension of bitwise operations

Introduction

I've been developing software using C/C++ for a very long time yet I still have to think twice when I encounter bitwise operations, let alone when I have to explain them to somebody else! For example:

    unsigned const STAT_ONE = 0x0001;
    unsigned const STAT_TWO = 0x0002;
    
    unsigned status = 0x0001;
    if(status & (STAT_ONE | STAT_TWO)) // Does this evaluate to true or false?
       DoSomething();

We all know that the preceding statement checks if both STAT_ONE and STAT_TWO bits are set then DoSomething() will be executed... or is it if either STAT_ONE or STAT_TWO bits are set? Lets see:

    0001 or   // STAT_ONE
    0010      // STAT_TWO
    ----
    0011 and  // STAT_ONE | STAT_TWO
    0001      // status
    ----
    0001      // status & (STAT_ONE | STAT_TWO)

Because the result is non-zero then DoSomething() will be executed. I think this can be very tricky, especially if the expressions get too complex. Isn't the intent of the following code easier to understand and less error-prone?

    unsigned const STAT_ONE = 0x0001;
    unsigned const STAT_TWO = 0x0002;

    unsigned status = 0x0001;
    if(isAnyBitSet(status, STAT_ONE | STAT_TWO)) // This evaluates to true, bit
                                                 // STAT_ONE is set and bit STAT_TWO 
                                                 // isn't. Same as previous example
       DoSomething();
    if(areAllBitsSet(status, STAT_ONE | STAT_TWO)) // This evaluates to false, 
                                                   // bit STAT_ONE is set but bit 
                                                   // STAT_TWO isn't
       DoSomething();

Also it's very convenient to access a bit's value by its position like this:

    if(isBitSetByPos(status, 5))   
       bitClearByPos(status, 5);

All the functions provided in the BitTools.h header are inlined so there is no size or run-time speed tradeoffs to worry about.

Templates

Bitmask-based functions

  • template <class T, class U><br>bool isAnyBitSet(T value, U mask)

    Returns true if any of the bits in mask is set in value. Defined as: (value & mask) != 0
       1010 and  // value
       0110      // mask
       ----
       0010      // Non-zero: true
  • template <class T, class U><br>bool areAllBitsSet(T value, U mask)

    Returns true if all the bits in mask are set in value. Defined as: (value & mask) == mask
       1010 and  // value
       1110      // mask
       ----
       1010      // 1010 == 1010: true
  • template <class T, class U><br>bool areAllBitsClear(T value, U mask)

    Returns true if all the bits in mask are cleared in value. Defined as: (value & mask) == 0
       1010 and  // value
       0101      // mask
       ----
       0000      // Zero: true
  • template <class T, class U><br>T setBits(T value, U mask)

    Returns value with the mask bits set. Defined as: value | mask
       1000 or   // value
       0110      // mask
       ----
       1110
  • template <class T, class U><br>T setBitsExcept(T value, U mask)

    Returns value with the all the bits set except the mask bits. Defined as: value | ~mask
       1001 not  // mask
       ----
       0110 or   // ~mask
       0001      // value
       ----
       0111
  • template <class T, class U><br>T clearBits(T value, U mask)

    Returns value with the mask bits cleared. Defined as: value & ~mask
       1001 not  // mask
       ----
       0110 and  // ~mask
       1111      // value
       ----
       0110
  • template <class T, class U><br>T clearBitsExcept(T value, U mask)

    Returns value with the all the bits cleared except the mask bits. Defined as: value & mask
       0010 and  // value
       0110      // mask
       ----
       0010
  • template <class T, class U><br>T setClearBits(T value, U add, U remove)

    Returns value with the add bits set and the remove bits cleared. Defined as: (value | add) & ~remove
       1101 or   // value
       0101      // add
       ----
       0111
    
       0001 not  // remove
       ---- 
       1110 and  // ~remove
       0111      // value | add
       ----
       0110
  • template <class T, class U, class V><br>T setBits(T value, U mask, V set)

    Returns value with the mask bits set or cleared depending on the value of set.

Position-based functions

  • template <class T><br>T setBitByPos(T value, unsigned char n)

    Returns value with the nth bit set. Defined as value | (1 << n)

  • template <class T><br>T clearBitByPos(T value, unsigned char n)

    Returns value with the nth bit cleared. Defined as value & ~(1 << n)

  • template <class T><br>bool isBitSetByPos(T value, unsigned char n)

    Returns true if value has the the nth bit set. Defined as (value & (1 << n)) != 0

  • template <class T><br>bool isBitClearByPos(T value, unsigned char n)

    Returns true if value has the the nth bit cleared. Defined as (value & (1 << n)) == 0

Conclusion

The templates contained in BitTools.h provide an easier and less error-prone way of expressing bitwise operations with no performance or size penalties compared to hand written code. I hope you find these functions as useful and easy to use as I did.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Eddie Velasquez

Software Developer (Senior)

United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralNone PinmemberJonathan de Halleux21:49 25 Feb '03  
GeneralWhy templates PinmemberBill Semaphore10:37 3 Jan '02  
GeneralRe: Why templates PinmemberNemanja Trifunovic11:12 3 Jan '02  
GeneralRe: Why templates PinmemberEddie Velasquez14:52 3 Jan '02  
GeneralASSERTs PinmemberMike Klimentiev10:20 2 Jan '02  
GeneralRe: ASSERTs PinmemberEddie Velasquez2:36 3 Jan '02  
GeneralRe: ASSERTs PinmemberMike Klimentiev8:06 3 Jan '02  
GeneralRe: ASSERTs PinmemberEddie Velasquez2:23 4 Jan '02  
GeneralRe: ASSERTs PinmemberMike Klimentiev8:41 4 Jan '02  
GeneralRe: ASSERTs PinmemberEddie Velasquez8:53 4 Jan '02  
GeneralStandard C MACRO version PinmemberDaniel May16:27 26 Dec '01  
GeneralRe: Standard C MACRO version PinmemberEddie Velasquez3:19 27 Dec '01  
GeneralRe: Standard C MACRO version PinmemberDaniel May3:23 27 Dec '01  
GeneralRe: Standard C MACRO version PinmemberEddie Velasquez4:11 27 Dec '01  
GeneralI think this is much more intuitive. PinmemberHenry Jacobs3:01 22 Dec '01  
GeneralI think this is less error prone Pinmemberokigan14:59 21 Dec '01  
GeneralRe: I think this is less error prone PinmemberEddie Velasquez15:13 21 Dec '01  
GeneralRe: I think this is less error prone PinmemberPhilippe Lhoste23:28 2 Jan '02  
GeneralRe: I think this is less error prone PinmemberEddie Velasquez2:40 3 Jan '02  
GeneralRe: I think this is less error prone PinmemberPhilippe Lhoste3:21 3 Jan '02  
GeneralRe: I think this is less error prone Pinmemberokigan5:33 3 Jan '02  
GeneralRe: I think this is less error prone PinmemberEddie Velasquez7:14 3 Jan '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 26 Dec 2001
Article Copyright 2001 by Eddie Velasquez
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid