Click here to Skip to main content
15,867,488 members
Articles / Programming Languages / Objective C

Easier bitwise Operations

Rate me:
Please Sign up or sign in to vote.
4.46/5 (11 votes)
25 Dec 2001CPOL2 min read 149.8K   760   40   23
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:

C++
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? Let's see:

C++
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?

C++
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();
C++
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:

C++
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

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

    Returns true if any of the bits in mask is set in value. Defined as: (value & mask) != 0

    C++
    1010 and  // value
    0110      // mask
    ----
    0010      // Non-zero: true
    
  • C++
    template <class T, class U>
    	bool areAllBitsSet(T value, U mask)

    Returns true if all the bits in mask are set in value. Defined as: (value & mask) == mask

    C++
    1010 and  // value
    1110      // mask
    ----
    1010      // 1010 == 1010: true
    
  • C++
    template <class T, class U>

    bool areAllBitsClear(T value, U mask)

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

    Returns value with the mask bits set. Defined as: value | mask

    C++
    1000 or   // value
    0110      // mask
    ----
    1110
    
  • C++
    template <class T, class U>
    	T setBitsExcept(T value, U mask)

    Returns value with all the bits set except the mask bits. Defined as: value | ~mask

    C++
    1001 not  // mask
    ----
    0110 or   // ~mask
    0001      // value
    ----
    0111
    
  • C++
    template <class T, class U>
    	T clearBits(T value, U mask)

    Returns value with the mask bits cleared. Defined as: value & ~mask

    C++
    1001 not  // mask
    ----
    0110 and  // ~mask
    1111      // value
    ----
    0110
    
  • C++
    template <class T, class U>
    	T clearBitsExcept(T value, U mask)

    Returns value with all the bits cleared except the mask bits. Defined as: value & mask

    C++
    0010 and  // value
    0110      // mask
    ----
    0010
    
  • C++
    template <class T, class U>
    	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

    C++
    1101 or   // value
    0101      // add
    ----
    0111
    
    0001 not  // remove
    ----
    1110 and  // ~remove
    0111      // value | add
    ----
    0110
    
  • C++
    template <class T, class U, class V>
    	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

  •  

    C++
    template <class T>
    	T setBitByPos(T value, unsigned char n)

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

  •  

    C++
    template <class T>
    	T clearBitByPos(T value, unsigned char n)

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

  •  

    C++
    template <class T>
    	bool isBitSetByPos(T value, unsigned char n)

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

  •  

    C++
    template <class T>
    	bool isBitClearByPos(T value, unsigned char n)

    Returns true if value has 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)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionNice Article Thank You Pin
Member 118470888-Jan-19 23:16
Member 118470888-Jan-19 23:16 
GeneralNone Pin
Jonathan de Halleux25-Feb-03 21:49
Jonathan de Halleux25-Feb-03 21:49 
GeneralWhy templates Pin
3-Jan-02 10:37
suss3-Jan-02 10:37 
GeneralRe: Why templates Pin
Nemanja Trifunovic3-Jan-02 11:12
Nemanja Trifunovic3-Jan-02 11:12 
GeneralRe: Why templates Pin
Eddie Velasquez3-Jan-02 14:52
Eddie Velasquez3-Jan-02 14:52 
There are a bunch of different kinds of integers: signed and unsigned chars, ints, longs, __int64s. Not one fits all possible needs.

Foot-and-Mouth disease is believed to be the first virus unable to spread through Microsoft Outlook
GeneralASSERTs Pin
Mike Klimentiev2-Jan-02 10:20
Mike Klimentiev2-Jan-02 10:20 
GeneralRe: ASSERTs Pin
Eddie Velasquez3-Jan-02 2:36
Eddie Velasquez3-Jan-02 2:36 
GeneralRe: ASSERTs Pin
Mike Klimentiev3-Jan-02 8:06
Mike Klimentiev3-Jan-02 8:06 
GeneralRe: ASSERTs Pin
Eddie Velasquez4-Jan-02 2:23
Eddie Velasquez4-Jan-02 2:23 
GeneralRe: ASSERTs Pin
Mike Klimentiev4-Jan-02 8:41
Mike Klimentiev4-Jan-02 8:41 
GeneralRe: ASSERTs Pin
Eddie Velasquez4-Jan-02 8:53
Eddie Velasquez4-Jan-02 8:53 
GeneralStandard C MACRO version Pin
Daniel May26-Dec-01 16:27
Daniel May26-Dec-01 16:27 
GeneralRe: Standard C MACRO version Pin
Eddie Velasquez27-Dec-01 3:19
Eddie Velasquez27-Dec-01 3:19 
GeneralRe: Standard C MACRO version Pin
Daniel May27-Dec-01 3:23
Daniel May27-Dec-01 3:23 
GeneralRe: Standard C MACRO version Pin
Eddie Velasquez27-Dec-01 4:11
Eddie Velasquez27-Dec-01 4:11 
GeneralI think this is much more intuitive. Pin
Henry Jacobs22-Dec-01 3:01
Henry Jacobs22-Dec-01 3:01 
GeneralI think this is less error prone Pin
Igor Okulist21-Dec-01 14:59
Igor Okulist21-Dec-01 14:59 
GeneralRe: I think this is less error prone Pin
Eddie Velasquez21-Dec-01 15:13
Eddie Velasquez21-Dec-01 15:13 
GeneralRe: I think this is less error prone Pin
Philippe Lhoste2-Jan-02 23:28
Philippe Lhoste2-Jan-02 23:28 
GeneralRe: I think this is less error prone Pin
Eddie Velasquez3-Jan-02 2:40
Eddie Velasquez3-Jan-02 2:40 
GeneralRe: I think this is less error prone Pin
Philippe Lhoste3-Jan-02 3:21
Philippe Lhoste3-Jan-02 3:21 
GeneralRe: I think this is less error prone Pin
Igor Okulist3-Jan-02 5:33
Igor Okulist3-Jan-02 5:33 
GeneralRe: I think this is less error prone Pin
Eddie Velasquez3-Jan-02 7:14
Eddie Velasquez3-Jan-02 7:14 

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

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