设置/取消设置单个位的简单方法

dje*_*dot 18 c++ bit-manipulation

现在我用它来设置/取消设置一个字节中的各个位:

if (bit4Set)
   nbyte |= (1 << 4);
else
   nbyte &= ~(1 << 4);
Run Code Online (Sandbox Code Playgroud)

但是,你不能以更简单/更优雅的方式做到这一点吗?就像在一次操作中设置或取消设置一样?

注意:我知道我可以写一个函数来做到这一点,我只是想知道我是否不会重新发明轮子.

Pas*_*uoq 13

当然!这将是比较明显的,如果你扩大了|=&=在你的代码,但你可以这样写:

nbyte = (nbyte & ~(1<<4)) | (bit4Set<<4);
Run Code Online (Sandbox Code Playgroud)

请注意,bit4Set必须为零或一个 - 不是任何非零值 - 为此起作用.

  • `nbyte =(nbyte&〜(1 << 4))| ((!! bit4Set)<< 4)`负责bit4Set不为零或一. (7认同)

Nor*_*ame 12

将它放在一个函数中,bool类型将对所有bitval输入强制执行0,1.

int change_bit(int val, int num, bool bitval)
{
    return (val & ~(1<<num)) | (bitval << num);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你让编译器在C++中内联这个函数,那么它就像你使用表达式本身一样快,而且你得到了可读性奖励. (5认同)

Ale*_* C. 6

这是一个完全合理且完全标准的习语.


Dan*_*ing 5

您是否考虑过为您的位分配助记符和/或标识符,而不是按编号引用它们?

举个例子,假设设置位4启动核反应堆SCRAM.我们称之为"第4位",而不是将其称为"第4位" INITIATE_SCRAM.以下是此代码的外观:

int const INITIATE_SCRAM = 0x10; // 1 << 4

...

if (initiateScram) {
    nbyte |= INITIATE_SCRAM;
} else {
    nbyte &= ~INITIATE_SCRAM;
}
Run Code Online (Sandbox Code Playgroud)

这不一定比原始代码更有效(在优化之后),但我认为它更清晰,并且可能更易于维护.