Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的位操作和标志测试_C_Bit Manipulation_Flags_Bitflags - Fatal编程技术网

C语言中的位操作和标志测试

C语言中的位操作和标志测试,c,bit-manipulation,flags,bitflags,C,Bit Manipulation,Flags,Bitflags,假设我有两个int类型的变量,a和b,还有一个标志F #define F <something> int a = <something> ; int b = <something> ; 为了测试它们是否都没有,我可以使用以下方法: if ( a & b & F ) if ( !((a & F) || (b & F)) ) 整个测试变成: if ( (a & b & F) && !((a

假设我有两个
int
类型的变量,
a
b
,还有一个标志
F

#define F <something>

int a = <something> ;
int b = <something> ;
为了测试它们是否都没有,我可以使用以下方法:

if ( a & b & F )
if ( !((a & F) || (b & F)) )
整个测试变成:

if ( (a & b & F) &&  !((a & F) || (b & F)) )
但这看起来太长太复杂了。有更简单的解决方案吗?

可以对“他们都没有”进行测试

合并标志、屏蔽和翻转逻辑


整个测试可以使用xor编写。(感谢马丁·詹姆斯的创意)


这意味着“不是(正是
a
b
中的一个具有
F
)”

您正在寻找位相等性,可以通过应用异或运算符
^
、反转结果和掩蔽进行测试

a^b
仅当
a
b
的对应位不同时,才将位设置为1。对于相同的对应位,结果位将设置为零

如果你颠倒结果,你会得到位元相等的结果:

~(a ^ b)
剩下的唯一一件事就是用
F
屏蔽,并检查是否相等:

if ((~(a ^ b) & F) == F) {
    ... // All bits indicated by F are set to the same value in a and b
}
也许是这个

!((a & F) ^ (b & F))

非异或…………尽管您想要测试,但为什么要使用
&&
?可能会单独为指令添加测试?是否授权
F
中正好有一位为1,或者
F
中没有或多个位可以为1?@MikeCAT保证
F
为非零。
!((a | b)和F)
这是德摩根定律吗?因为我觉得
!((a | b)和F)
相当于
!((a&F)|(b&F))
而不是
!((a&F)| |(b&F))
@BiteBytes无
!((a&F)|(a&F))
!((a&F)|(a&F))
相当于
!((a | b)&F)
:前两个都使用
a
两次,而最后一个使用
a
b
@BiteBytes
(a | b)&F
相当于
(a&F)|(b&F)
,并不等同于
(a&F)|(b&F)
,不同之处在于
|
运算符执行按位或运算,而
|
运算符执行逻辑或运算。但是添加
运算符,这不符合逻辑,对于所有运算符,它们都应该是等效的。为什么要检查相等性?如果(~(a^b)&F))就足够了,那么
不是吗?如果最后没有相等检查,当某些位(但不一定是所有位)匹配时,您将得到“true”。它也不适用于零的F(当没有检查任何位时,答案应该是“true”)。
~(a^b)&F==F
-它是不正确的,它与
~(a^b)&1
@dasblinkenlight相同,即使更正了它也会给出最差的代码:)操作符优先级问题:将
~(a^b)&F==F)
更改为
(~(a^b)&F)==F)
,其可读性明显低于
!((a^b)和F)
可读性更强,但可能比
多出一个操作码!((a^b)和F)
。另外,由于优雅的对称性,可能会使读者认为它适用于不同的标志,如
!((a&F1)^(b&F2))
这不是真的。是的-这是故意的,因为OP正在学习位运算。尽管优化程度不同,但其输出相同。有趣的是,gcc不同于clang在
-O0
产生相同的代码,clang不同于gcc在
-O2
产生相同的代码,gcc不同于与
jmp
@chqrlie共享代码,所选解决方案不起作用:)并在纠正最坏情况时产生代码code@chqrlie我只测试了gcc
if ((~(a ^ b) & F) == F) {
    ... // All bits indicated by F are set to the same value in a and b
}
!((a & F) ^ (b & F))