将位与布尔值进行比较

共4个回答,已解决, 标签: c gcc boolean bitwise-operators

看似简单的问题: 说我有一组标志,编码在一个 uint16_tflags. For example, AMAZING_FLAG = 0x02。现在,我有一个功能。这个函数需要检查我是否想改变标志,因为如果我想这样做,我需要写入 flash。这是昂贵的。因此,我想要一个检查,它告诉我标志 & AMAZING_FLAG 是否 “等于” doSet。这是第一个想法:

SetAmazingFlag (bool doSet)
{
如果 ((标志 & AMAZING_FLAG)!= (doSet?AMAZING_FLAG: 0)) {
//真的很贵的东西
//更新标志
}
}

现在我有一个很难阅读的 if 语句。我觉得应该有更好的方法,比如

如果 ((标志 & AMAZING_FLAG)!= doSet) {

}

但这实际上并不起作用,true似乎等于 0x01。

所以,有没有一个整洁的方法来比较一个布尔?

第1个答案(采用)
    To convert any non-zero number to 1 (true), there is an old trick: apply the ! (not) operator twice.
如果 (!! (flags & AMAZING_FLAG)!= doSet) {
第2个答案
    You need to convert the bit mask to a boolean statement, which in C is equivalent to values 0 or 1.
  • (flags & AMAZING_FLAG) != 0。最常见的方式。

  • !!(flags & AMAZING_FLAG)。有点普通,也可以使用,但有点神秘。

  • (bool)(flags & AMAZING_FLAG)。仅来自 C99 和 beyond 的现代 C 方式。

采取上述任何备选方案,然后将其与您的布尔使用进行比较!= or ==

第3个答案
    From a logical point of view, flags & AMAZING_FLAG is only a bit operation masking all other flags. The result is a numerical value.

要接收到一个布尔值,您可以使用一个比较

(标志 & AMAZING_FLAG) = = AMAZING_FLAG

并且现在可以将此逻辑值与doSet

如果 (标志 & AMAZING_FLAG) = = AMAZING_FLAG)!= doSet)

在 C 中可能有缩写,因为数字到布尔值的隐式转换规则。所以你也可以写

如果 (!(标志 & AMAZING_FLAG) = = doSet)

写得更简洁。但是前一版本在可读性方面更好。

第4个答案
    You can create a mask based on doSet value:
# 定义 AMAZING_FLAG_IDX 1
# 定义 AMAZING_FLAG (1u <<AMAZING_FLAG_IDX)
.

Uint16_t set_mask = doSet <<AMAZING_FLAG_IDX;

现在你的支票可以是这样的:

SetAmazingFlag (bool doSet)
{
Const uint16_t set_mask = doSet <<AMAZING_FLAG_IDX;

如果 (标志 & set_mask) {
//真的很贵的东西
//更新标志
}
}

在某些体系结构上,!!可能被编译到一个分支,通过这个,你可能有两个分支:

  1. 标准化!!(expr)
  2. 比较至doSet

我的提议的优势是有保证的单一分支。

注意:确保你不会通过向左移动超过 30 来引入未定义的行为。这可以很容易地通过static_assert(AMAZING_FLAG_IDX < 31, "Invalid AMAZING_FLAG_IDX");

相关问题

我投的是 malloc 的结果吗? 为什么是统计:: st _ size 0 为设备, 但同时 lseek 正确地定义了设备大小? 允许在易失对象上进行优化 升级到 Catalina 10.15 后,无法在 Mac 上编译 C 程序 如何禁用没有命令行开关的 gcc 警告? 为什么这个函数调用在通过有类型的函数指针调用它之后表现得很理智? 此类型和函数是否有现有名称? 将位与布尔值进行比较 在 bool 中设置额外的位使得它同时为 true 和 false 什么是 ^ b 和 (a & b)< 1?></ 1?> &lt;在 Java 中是什么意思?[关闭]