开发者

Change a bit of an integer [duplicate]

This question already has answers here: How do I set, clear, and toggle a single bit? (27 answe开发者_JAVA百科rs) Closed 8 years ago.

We have an integer number

int x = 50;

in binary, it's

00110010

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


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!


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));


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


Simple, since you have, or whatever value you have,

int x = 50;

To set 4th bit (from right) programatically,

int y = x | 0x00000008;

Because, 0x prefixed before a number means it's hexadecimal form. So, 0x0 = 0000 in binary, and 0x8=1000 in binary form. That explains the answer.


Try one of these functions in C language to change n bit

char bitfield;

// start at 0th position

void chang_n_bit(int n, int value)
{
    bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}

void chang_n_bit(int n, int value)
{
    bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}

void chang_n_bit(int n, int value)
{
    if(value)
        bitfield |= 1 << n;
    else
        bitfield &= ~0 ^ (1 << n);
}

char print_n_bit(int n)
{
    return (bitfield & (1 << n)) ? 1 : 0;
}


You can use binary AND and OR to toggle the fourth bit.

To set the fourth bit on x, you would use x |= 1<<3;, 1<<3 being a left shift of 0b0001 by three bits producing 0b1000.

To clear the fourth bit on x, you would use x &= ~(1<<3);, a binary AND between 0b00110010 (x) and (effectively) 0b11110111, masking out every bit in x that is not in position four, thus clearing it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜