我遇到了以下代码段
if( 0 != ( x ^ 0x1 ) )
encode( x, m );
x ^ 0x1
是什么意思?这是一种标准技术吗?
答案 0 :(得分:277)
XOR运算(x ^ 0x1
)将位0反转。因此表达式实际上意味着:如果x的位0为0,或者x的任何其他位为1,则表达式为真。
相反,如果x == 1,则表达式为false。
所以测试与:
相同if (x != 1)
因此(可以说)不必要地混淆了。
答案 1 :(得分:78)
^
是按位XOR操作0x1
以十六进制表示法为1
x ^ 0x1
将反转x
的最后一位(如果您不清楚,请参阅上面链接中的XOR真值表。)因此,如果(0 != ( x ^ 0x1 ))
大于1或者x
的最后一位为0,则条件x
将为真。这只留下x == 1作为值哪个条件是假的。所以它相当于
if (x != 1)
P上。 S. Hell是一种实现这种简单条件的方法,我想补充一下。不要那样做。如果您必须编写复杂的代码,发表评论。求求你。
答案 2 :(得分:49)
这似乎是一个过于简单的解释,但如果有人想慢慢地通过它,那就是:
^
是c,c ++和c#中的bitwise XOR运算符。
按位XOR采用两个相等长度的位模式并执行 对每对相应位进行逻辑异或运算。
异或是一种逻辑运算,只要两者都输出为真 输入不同(一个是真的,另一个是假的)。
a xor b 的truth table:
a b a xor b
----------------------------
1 1 0
1 0 1
0 1 1
0 0 0
让我们来说明二进制级别的0 == ( x ^ 0x1 )
表达式:
what? xxxxxxxx (8 bits)
xor 00000001 (hex 0x1 or 0x01, decimal 1)
gives 00000000
---------------------------
the only answer is 00000001
这样:
0 == ( x ^ 0x1 ) => x == 1
0 != ( x ^ 0x1 ) => x != 1
答案 3 :(得分:34)
它是异或(XOR)运算符。要了解它是如何工作的,您可以运行这个简单的代码
std::cout << "0x0 ^ 0x0 = " << ( 0x0 ^ 0x0 ) << std::endl;
std::cout << "0x0 ^ 0x1 = " << ( 0x0 ^ 0x1 ) << std::endl;
std::cout << "0x1 ^ 0x0 = " << ( 0x1 ^ 0x0 ) << std::endl;
std::cout << "0x1 ^ 0x1 = " << ( 0x1 ^ 0x1 ) << std::endl;
输出
0x0 ^ 0x0 = 0
0x0 ^ 0x1 = 1
0x1 ^ 0x0 = 1
0x1 ^ 0x1 = 0
所以这个表达
0 != ( x ^ 0x1 )
只有当x!= 0x1时,才会相等。
它不会改变x本身。它仅检查x是否等于0或1.此rxpression可以更改为
if ( x != 0x1 )
答案 4 :(得分:19)
它检查x
实际上不是0x1
... xor
x
0x1
只有x
才会导致0x1
是{{1}} ...这是一种主要用于汇编语言的旧技巧
答案 5 :(得分:18)
^
运算符是按位xor。 0x1
是数字1
,写为十六进制常量。
因此,x ^ 0x1
计算的值与x
相同,但最低有效位会被翻转。
代码只是将x与1进行比较,而且非常复杂和模糊。
答案 6 :(得分:11)
xor(exclusive或)运算符最常用于反转一个或多个位。 操作是询问其中一个位是否为1,这导致下面的真值表(A和B是输入,Y是输出):
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
现在这个代码的目的似乎是检查最后一位是否为1,其他位是0,这等于if ( x != 1 )
。
这种模糊方法的原因可能是先前的位操作技术已被使用,并且可能在程序中的其他位置使用。
答案 7 :(得分:8)
^
在xor operator
中按位c
。在你的情况下,x与x进行xor'ed,例如x
的值为10,然后是10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11d
,因此条件变为真。
答案 8 :(得分:8)
按位测试似乎是故意的混淆,但如果底层数据是来自IBM大型机系统的公司数据,则可能只是编写代码以反映原始文档。 IBM数据格式可以追溯到20世纪60年代,并经常将标志编码为一个字内的单个位以节省存储空间。在修改格式时,在现有记录的末尾添加了标志字节以保持向后兼容性。例如,SMF记录的文档可能会显示汇编语言代码,以测试单个记录中三个不同单词中的三个单独位,以确定数据是输入文件。 我对TCP / IP内部的了解要少得多,但你也可以在那里找到位标志。
答案 9 :(得分:7)
运算符^是bitwise-xor(参见&amp;,|)。位对的结果是,
0 ^ 0 == 0
0 ^ 1 == 1
1 ^ 0 == 1
1 ^ 1 == 0
所以表达,
( x ^ 0x1 )
反转/翻转x的第0位(保持其他位不变)。
考虑x是否可以有除0x0和0x1之外的值?当x是单个位字段时,它只能有值0x0和0x1,但是当x是int(char / short / long / etc)时,bit0之外的位会影响表达式的结果。
给定的表达式允许bit0旁边的位影响结果,
if ( 0 != ( x ^ 0x1 ) )
与此(更简单)表达式具有同等的真实性,
if ( x ^ 0x1 )
请注意,此表达式仅检查bit0,
if( 0x1 & ( x ^ 0x1 ) )
因此,所呈现的表达式实际上是两个表达式检查相结合,
if( ( x & ~0x1 ) //look at all bits besides bit0
|| ( x ^ 0x1 ) ) //combine with the xor expression for bit0
作者是否打算只检查bit0,并打算使用这个表达式,
if( 0x1 & ( x ^ 0x1 ) )
或者作者是否打算将bit1-bitN的值和bit0的xor组合在一起?
答案 10 :(得分:7)
我正在添加一个新答案,因为没有人真正解释如何直观地得到答案。
+
的倒数是-
^
的倒数为^
。
如何解决0 != x - 1
的{{1}}?双方 x
:+ 1
→0 + 1 != x - 1 + 1
。
您如何解决1 != x
的{{1}}?您 0 != x ^ 1
双方:x
→^ 1
。
答案 11 :(得分:6)
我猜在x
中还有其他位或位字段值,这是为了测试只设置了低位。在上下文中,我猜这是默认的,因此可以跳过这个和一些相关的m
(编码可能更昂贵)的编码,因为它们必须都是默认值,初始化为构造函数或类似的。
解码器必须能够推断出这些值缺失。如果它们位于某个结构的末尾,则可以通过始终存在的length
值进行通信。
答案 12 :(得分:4)
XOR在C#标志枚举中很有用。要从枚举值中删除单个标志,必须使用xor运算符(引用here)
示例:
[Flags]
enum FlagTest { None 0x0, Test1 0x1, Test2 0x2, Test3 0x4}
FlagTest test = FlagTest.Test2 | FlagTest.Test3;
Console.WriteLine(test); //Out: FlagTest.Test2 | FlagTest.Test3
test = test ^ FlagTest.Test2;
Console.WriteLine(test); //Out: FlagTest.Test3
答案 13 :(得分:4)
有很多好的答案,但我想以更简单的方式思考它。
if ( 0 != ( x ^ 0x1 ) );
首先。如果参数为零,则if语句仅为false。这意味着比较不等于零是没有意义的。
if ( a != 0 );
// Same as
if ( a );
这样我们就得到了:
if ( x ^ 0x1 );
一个XOR。 XOR的作用基本上是检测不同的位。因此,如果所有位都相同,它将返回0.因为0为假,所以它返回false的唯一时间是所有位都相同。因此,如果参数相同则为false,如果它们不同则为true ...就像不等于运算符一样。
if ( x != 0x1 );
如果事实是,两者之间的唯一区别是!=
将返回0或1,而^
将返回任何数字,但 truthyness 的结果将是总是一样的。一个简单的思考方式是。
(b != c) === !!(b ^ c) // for all b and c
最后的“简化”是将0x1
转换为1的十进制数。因此,您的陈述相当于:
if ( x != 1 )
答案 14 :(得分:1)
^是bitwise XOR运算符
如果x = 1
00000001 (x) (decimal 1)
00000001 (0x1) (decimal 1)
XOR 00000000 (0x0) (decimal 0)
这里0 ==(x ^ 0x1)
如果x = 0
00000000 (x) (decimal 0)
00000001 (0x1) (decimal 1)
XOR 00000001 (0x1) (decimal 0)
这里0!=(x ^ 0x1)
xor b的真值表:
a b a xor b
----------------------------
1 1 0
1 0 1
0 1 1
0 0 0
代码只是意味着
答案 15 :(得分:1)
可能正在被使用的标准技术,在这里,为了清晰起见,重复出现在周围环境中的习语,而不是通过用算术上更简单的习语替换它来混淆它。但在语境上毫无意义。
周围的代码可能经常引用(x ^ 1)
,或者测试可能会询问“如果位0是否相反,这个位掩码是否为空?”。
鉴于条件导致某些内容encode()
,可能是在上下文中,位0的默认状态已被其他因素反转,并且如果任何位偏离,我们只需编码额外信息从他们的默认值(通常全零)。
如果你将表达脱离背景并询问它的作用,你会忽略潜在的意图。您也可以查看编译器的汇编输出,看看它只是与1进行直接相等比较。
答案 16 :(得分:0)
到目前为止,我看到答案错过了处理XOR
的简单规则。在不详细说明^
和0x
的含义(以及if
和!=
等)的情况下,可以使用以下事实对表达式0 != (x^1)
进行如下重写: (a^a)==0
:
0 != (x^1) <=> [xor left and right side by 1]
(0^1) != (x^1^1) <=>
1 != x