13,830,323 members
alternative version

Stats

140.7K views
40 bookmarked
Posted 20 Dec 2001
Licenced CPOL

Easier bitwise Operations

, 25 Dec 2001
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? Let's 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

• ```template <class T, class U>

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

```1010 and  // value
----
0010      // Non-zero: true
```
• ```template <class T, class U>

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

```1010 and  // value
----
1010      // 1010 == 1010: true
```
• `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`
```1010 and  // value
----
0000      // Zero: true
```
• ```template <class T, class U>

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

```1000 or   // value
----
1110
```
• ```template <class T, class U>

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

```1001 not  // mask
----
0001      // value
----
0111
```
• ```template <class T, class U>

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

```1001 not  // mask
----
1111      // value
----
0110
```
• ```template <class T, class U>

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

```0010 and  // value
----
0010
```
• ```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`

```1101 or   // value
----
0111

0001 not  // remove
----
1110 and  // ~remove
----
0110
```
• ```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

•

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

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

•

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

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

•

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

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

•

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

Returns `true` if `value` has the `n`th 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.

Share

 Software Developer (Senior) United States
No Biography provided

You may also be interested in...

 First Prev Next
 Nice Article Thank You Member 118470889-Jan-19 0:16 Member 11847088 9-Jan-19 0:16
 None Jonathan de Halleux25-Feb-03 22:49 Jonathan de Halleux 25-Feb-03 22:49
 Why templates 3-Jan-02 11:37 3-Jan-02 11:37
 Re: Why templates Nemanja Trifunovic3-Jan-02 12:12 Nemanja Trifunovic 3-Jan-02 12:12
 Re: Why templates Eddie Velasquez3-Jan-02 15:52 Eddie Velasquez 3-Jan-02 15:52
 ASSERTs Mike Klimentiev2-Jan-02 11:20 Mike Klimentiev 2-Jan-02 11:20
 Re: ASSERTs Eddie Velasquez3-Jan-02 3:36 Eddie Velasquez 3-Jan-02 3:36
 Re: ASSERTs Mike Klimentiev3-Jan-02 9:06 Mike Klimentiev 3-Jan-02 9:06
 Re: ASSERTs Eddie Velasquez4-Jan-02 3:23 Eddie Velasquez 4-Jan-02 3:23
 Re: ASSERTs Mike Klimentiev4-Jan-02 9:41 Mike Klimentiev 4-Jan-02 9:41
 Re: ASSERTs Eddie Velasquez4-Jan-02 9:53 Eddie Velasquez 4-Jan-02 9:53
 Standard C MACRO version Daniel May26-Dec-01 17:27 Daniel May 26-Dec-01 17:27
 Re: Standard C MACRO version Eddie Velasquez27-Dec-01 4:19 Eddie Velasquez 27-Dec-01 4:19
 Re: Standard C MACRO version Daniel May27-Dec-01 4:23 Daniel May 27-Dec-01 4:23
 Re: Standard C MACRO version Eddie Velasquez27-Dec-01 5:11 Eddie Velasquez 27-Dec-01 5:11
 I think this is much more intuitive. Henry Jacobs22-Dec-01 4:01 Henry Jacobs 22-Dec-01 4:01
 I think this is less error prone Igor Okulist21-Dec-01 15:59 Igor Okulist 21-Dec-01 15:59
 Re: I think this is less error prone Eddie Velasquez21-Dec-01 16:13 Eddie Velasquez 21-Dec-01 16:13
 Re: I think this is less error prone Philippe Lhoste3-Jan-02 0:28 Philippe Lhoste 3-Jan-02 0:28
 Re: I think this is less error prone Eddie Velasquez3-Jan-02 3:40 Eddie Velasquez 3-Jan-02 3:40
 Re: I think this is less error prone Philippe Lhoste3-Jan-02 4:21 Philippe Lhoste 3-Jan-02 4:21
 Re: I think this is less error prone Igor Okulist3-Jan-02 6:33 Igor Okulist 3-Jan-02 6:33
 Re: I think this is less error prone Eddie Velasquez3-Jan-02 8:14 Eddie Velasquez 3-Jan-02 8:14
 Last Visit: 17-Jan-19 7:15     Last Update: 17-Jan-19 7:15 Refresh 1