Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change a bit of an integer [duplicate]

We have an integer number

int x = 50;

in binary, it's

00110010

How can I change the fourth (4th) bit programatically?

like image 991
pedram Avatar asked Aug 02 '11 18:08

pedram


People also ask

How do you flip a bit of a number?

Flipping a bit means toggling or inverting the current bit status. If the current bit is set i.e. 1 than invert it to 0 and vice versa. To flip all bits of a binary number you can run loop from 0 to size of the integer and flip individual bit at a time.

How do I change a single bit?

Toggling a bitThe XOR operator ( ^ ) can be used to toggle a bit. number ^= 1UL << n; That will toggle the n th bit of number .

How to change the bit of a number in cpp?

Introduction to Left shift and Right shift operatorThe left shift and right shift operators are used to shift the bits of a number either left or right as specified. RIGHT SHIFT(>>): it accepts to numbers, and shifts the first number to the right, number of times as specified by the second number.


3 Answers

You can set the fourth bit of a number by OR-ing it with a value that is zero everywhere except in the fourth bit. This could be done as

x |= (1u << 3);

Similarly, you can clear the fourth bit by AND-ing it with a value that is one everywhere except in the fourth bit. For example:

x &= ~(1u << 3);

Finally, you can toggle the fourth bit by XOR-ing it with a value that is zero everywhere except in the fourth bit:

x ^= (1u << 3);

To see why this works, we need to look at two things:

  1. What is the behavior of the << operator in this context?
  2. What is the behavior of the AND, OR, and XOR operators here?

In all three of the above code snippets, we used the << operator to generate a value. The << operator is the bitwise shift-left operator, which takes a value and then shifts all of its bits some number of steps to the left. In your case, I used

1u << 3

to take the value 1 (which has binary representation 1) and to then shift all its bits over three spots, filling in the missing values with 0. This creates the binary value 1000, which has a bit set in the fourth bit.

Now, why does

x |= (1u << 3);

set the fourth bit of the number? This has to do with how the OR operator works. The |= operator is like += or *= except for bitwise OR - it's equivalent to

x = x | (1u << 3);

So why does OR-ing x with the binary value 1000 set its fourth bit? This has to do with the way that OR is defined:

0 | 0  == 0
0 | 1  == 1
1 | 0  == 1
1 | 1  == 1

More importantly, though, we can rewrite this more compactly as

x | 0  == x
x | 1  == 1

This is an extremely important fact, because it means that OR-ing any bit with zero doesn't change the bit's value, while OR-ing any bit with 1 always sets that bit to one. This means that when we write

x |= (1u << 3);

since (1u << 3) is a value that is zero everywhere except in the fourth bit, the bitwise OR leaves all the bits of x unchanged except for the fourth bit, which is then set to one. More generally, OR-ing a number with a value that is a series of zeros and ones will preserve all the values where the bits are zero and set all of the values where the bits are one.

Now, let's look at

x &= ~(1u << 3);

This uses the bitwise complement operator ~, which takes a number and flips all of its bits. If we assume that integers are two bytes (just for simplicity), this means that the actual encoding of (1u << 3) is

0000000000001000

When we take the complement of this, we get the number

1111111111110111

Now, let's see what happens when we bitwise AND two values together. The AND operator has this interesting truth table:

0 & 0   == 0
0 & 1   == 0
1 & 0   == 0
1 & 1   == 1

Or, more compactly:

x & 0   == 0
x & 1   == x

Notice that this means that if we AND two numbers together, the resulting value will be such that all of the bits AND-ed with zero are set to zero, while all other bits are preserved. This means that if we AND with

~(1u << 3)

we are AND-ing with

1111111111110111

So by our above table, this means "keep all of the bits, except for the fourth bit, as-is, and then change the fourth bit to be zero."

More generally, if you want to clear a set of bits, create a number that is one everywhere you want to keep the bits unchanged and zero where you want to clear the bits.

Finally, let's see why

x ^= (1u << 3)

Flips the fourth bit of the number. This is because the binary XOR operator has this truth table:

0 ^ 0  == 0
0 ^ 1  == 1
1 ^ 0  == 1
1 ^ 1  == 0

Notice that

x ^ 0  == 0
x ^ 1  == ~x

Where ~x is the opposite of x; it's 0 for 1 and 1 for 0. This means that if we XOR x with the value (1u << 3), we're XOR-ing it with

0000000000001000

So this means "keep all the bits but the fourth bit set as is, but flip the fourth bit." More generally, if you want to flip some number of bits, XOR the value with a number that has zero where you want to keep the bits intact and one where you want to flip this bits.

Hope this helps!

like image 144
templatetypedef Avatar answered Oct 22 '22 08:10

templatetypedef


You can always use std::bitset which makes modifying bits easy.

Or you can use bit manipulations (assuming you mean 4th bit counting at one. Don't subtract 1 if you mean counting from 0). Note that I use 1U just to guarantee that the whole operation happens on unsigned numbers:

To set: x |= (1U << (4 - 1));

To clear: x &= ~(1U << (4 - 1));

To toggle: x ^= (1U << (4 - 1));

like image 43
Mark B Avatar answered Oct 22 '22 09:10

Mark B


To set the fourth bit, OR with 00001000 (binary).

To clear the fourth bit, AND with 11110111 (binary).

To toggle the fourth bit, XOR with 00001000 (binary).

Examples:

00110010 OR 00001000 = 00111010

00110010 AND 11110111 = 00110010

00110010 XOR 00001000 = 00111010

like image 8
Patrick87 Avatar answered Oct 22 '22 08:10

Patrick87