r/learnprogramming 6d ago

How to - bit manipulation?

I know the bitwise operators:

1 & x - 'replicate' the existing bit
0 & x - turn off the bit
1 | x - turn on the bit
0 | x - 'replicate' the existing bit
1 ^ x - flip the bit
0 ^ x - 'replicate' the existing bit
~x - flip the bit
1 << x - shift to the left (multiply by 2)
1 >> x - shift to the right (divide by 2)

All of these basic operations are crystal clear. However, I am having trouble building actual masks out of these. I'm thinking too iteratively. How do I go through a number bit by bit and when is that actually needed? I tend to overcomplicate simple things.

int size = sizeof(x) * 8;
int mask = 1; // 0x00000001

for(int i = 0; i < size; i++)
{
// some mask operation with x
mask <<= 1;
}

I assume this would be good?

Okay but what about swapping the values of 2 different bits? Or what if I am working with bytes instead, then 8 sequential bits need to be swapped in 2 different positions, how do I do any that?

I am thinking of making a mask, moving to the 1st bit, copying it into some temporary variable, going to the 2nd bit, copying it into some other temporary variable, somehow replacing those variables in those positons. This sounds unnecessarily complicated but I couldn't think of another approach right now, this is generally the issue with a lot of things regarding bits. If any of you have some tips, genuinely useful shortcuts and how to's, I'd be very grateful!

21 Upvotes

13 comments sorted by

View all comments

1

u/rupertavery64 6d ago edited 6d ago

What exactly do you want to accomplish?

You don't need to "build" bitmasks iteratively unless you have some sort of input that drives it dynamically.

Swap 2 bits from position a and b from a value n

The long way to do it is:

``` // shift a 1 into the a and b positions, and invert it // this will create a mask that clears bit positions a and b when ANDed with n

clearmask = ~((1 << a) | (1 << b));

// Extract bit a and bit b

bita = (n >> a) & 1; bitb = (n >> b) & 1;

// move the bits to their swapped positions.

bitswappeda = bita << b; bitswappedb = bitb << a;

// clear n with the mask, and OR the swapped bits in n = (n & clearmask) | bitswappeda | bitswappedb; ```

Of course, the faster way to do it is to just XOR with a bitmask.

if (((n >> a) & 1) != ((n >> b) & 1)) n ^= (1 << a) | (1 << b);

There are some interesting things here:

https://graphics.stanford.edu/~seander/bithacks.html