修改字节中的特定位

Modify specific bit in byte

我需要修改(!不是切换异或!)字节值中的特定位。我有:

  1. 来源byte(例如b11010010);
  2. 要修改的位索引(例如4);
  3. 位的新值(01)。

现在,我需要什么。如果新值为 0,则位 [4] 必须设置为 0。如果新值为 1,则位 [4] 必须设置为 1.

一般部分:

var bitIndex = 4;
var byte = b11010010;
var mask = 1 << bitIndex;
var newValue = 1;

这是最简单的方法:

if(newValue == 1)
    byte |= mask; // set bit[bitIndex]
else
    byte &= ~mask; // drop bit[bitIndex]

另一种方法允许在没有 if else 语句的情况下执行此操作,但看起来很难理解:

byte = byte & ~mask | (newValue << bitIndex) & mask

这里,第一个 AND 丢弃 bit[bitIndex],第二个 AND 计算 bit[bitIndex] 的新值,OR 设置 bit[bitIndex] 计算值,不管是 0 还是 1.

有没有更简单的方法将特定位设置为给定值?

执行此操作的规范方法是:

byte ^= (-newValue ^ byte) & (1 << n);

如果 newValue == 1,位 n 将被设置,如果 newValue == 0,位 n 将被清除

(newValue << bitIndex) 只设置了一位,不需要 & mask.

所以你只有 5 次操作。

byte = byte & ~(1 << bitIndex) | (newValue << bitIndex); // bitIndex'th bit becomes newValue

它仍然足够复杂,值得评论,但很容易看出评论是正确的,因为它是两个容易识别的操作链接在一起(不像当前接受的答案,它需要每个 reader 坐下来想一想)