(x ^ 0x1)!= 0是什么意思?
我遇到了下面的代码片段
if( 0 != ( x ^ 0x1 ) ) encode( x, m );
x ^ 0x1
是什么意思? 这是一些标准的技术?
异或操作( x ^ 0x1
)反转位0.因此,expression式有效的意思是:如果x的位0为0,或者x的任何其他位为1,则expression式为真。
相反,如果x == 1,则expression式为false。
所以testing是一样的:
if (x != 1)
因此(可以说)不必要地混淆。
-
^
是按位XOR操作 - hex表示法中的
0x1
是1
-
x ^ 0x1
将反转x ^ 0x1
的最后一位(参考上面链接中的XOR真值表,如果不清楚的话)。
因此,如果x
大于1,或者x
的最后一位是0,则条件(0 != ( x ^ 0x1 ))
将为真。只有x == 1时,条件将为false 。 所以相当于
if (x != 1)
PS地狱的方式来实现这样一个简单的条件,我可以补充说。 不要这样做。 如果您必须编写复杂的代码, 请发表评论 。 我请求您。
这可能看起来是过于简单的解释,但如果有人想慢慢地经过它,
^
是c,c ++和c#中的按位异或运算符。
按位XOR采用长度相等的两位模式,并对每对相应位执行逻辑异或运算。
“异或”是一种逻辑运算,只要两个input不同(一个为真,另一个为假),则输出为真。
xor b的真值表 :
aba xor b ---------------------------- 1 1 0 1 0 1 0 1 1 0 0 0
所以我们来举例说明二进制级别的0 == ( x ^ 0x1 )
expression式:
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
它是异或(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
所以这个expression
0 != ( x ^ 0x1 )
只有当x!= 0x1时才是相等的。
它不会改变x本身。 它只检查x是否等于0或1.这个expression式可以改为
if ( x != 0x1 )
它检查x
是否实际上不是0x1
… xor
ing x
与0x1
将导致0只有当x
是0x1
…这是一个古老的技巧,主要用于汇编语言
^
运算符是按位异或。 而0x1
是数字1
,写成hex常量。
因此, x ^ 0x1
计算出一个与x
相同的新值,但最低有效位被翻转。
代码只不过是用一个非常复杂和模糊的方式比较x和1而已。
xor(exclusive或)运算符最常用于反转一个或多个位。 操作是询问是否其中一个比特是1,这导致以下真值表(A和B是input,Y是输出):
ABY 0 0 0 0 1 1 1 0 1 1 1 0
现在这个代码的目的似乎是检查是否激动最后一位是1,其他是0,这等于if ( x != 1 )
。 这种难以理解的方法的原因可能是以前的位操作技术已经被使用,并且可能在程序的其他地方被使用。
^
是在c
按位xor operator
。 在你的情况下,x与x相异。例如, x
的值为10,那么10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11d
所以条件成立。
按位testing似乎是故意的混淆,但是如果底层数据是来自IBM大型机系统的公司数据,则可能只是代码是为了反映原始文档而编写的。 IBM的数据格式可以追溯到20世纪60年代,并且频繁地将标志作为一个字内的单个位来编码以节省存储空间 当格式被修改时,在现有logging的末尾添加标志字节以保持向后兼容性。 例如,SMFlogging的文档可能会显示汇编语言代码,以testing单个logging中三个不同单词中的三个单独位,以确定数据是input文件。 我对TCP / IP内部知道的知之甚less,但是你也可能在那里find位标志。
运算符^是按位异或(参见&,|)。 一对一的结果是,
0 ^ 0 == 0 0 ^ 1 == 1 1 ^ 0 == 1 1 ^ 1 == 0
所以expression,
( x ^ 0x1 )
反转/翻转x的第0位(保持其他位不变)。
考虑x是否可以具有除0x0和0x1之外的值? 当x是单个位字段时,它可以只有值0x0和0x1,但是当x是一个int(char / short / long / etc)时,bit0之外的位可以影响expression式的结果。
给定的expression式允许bit0旁边的位影响结果,
if ( 0 != ( x ^ 0x1 ) )
这个(简单的)expression式具有相同的真实性,
if ( x ^ 0x1 )
请注意,这个expression式只会检查bit0,
if( 0x1 & ( x ^ 0x1 ) )
所以提出的expression式实际上结合了两个expression式检查,
if( ( x & ~0x1 ) //look at all bits besides bit0 || ( x ^ 0x1 ) ) //combine with the xor expression for bit0
作者是否打算只检查bit0,并打算使用这个expression式,
if( 0x1 & ( x ^ 0x1 ) )
还是作者打算将bit1-bitN和bit0的异或值相结合?
我添加了一个新的答案,因为没有人真正解释如何直观地得到答案。
+
的倒数是-
。
^
的倒数是^
。
你如何解决0 != x - 1
for x
? 你+ 1
到两边: 0 + 1 != x - 1 + 1
→ 1 != x
。
你如何解决0 != x ^ 1
for x
? 你^ 1
双方: 0 ^ 1 != x ^ 1 ^ 1
→ 1 != x
。
我猜测x
中还有其他位或位域值,这是为了testing只有低位被设置。 在上下文中,我猜测这是默认值,因此编码这个和一些相关的m
(可能更昂贵的编码)可以跳过,因为它们都必须是默认值,在构造函数中初始化或类似。
不知何故解码器必须能够推断出这些值是丢失的。 如果它们处于某个结构的末尾,则可以通过始终存在的length
值进行通信。
异或在C#标志枚举中很有用。 要从枚举值中移除单个标志,必须使用异或运算符(参考这里 )
例:
[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
有很多很好的答案,但我想以一种更简单的方式来考虑。
if ( 0 != ( x ^ 0x1 ) );
首先。 如果参数为零,则if语句仅为false。 这意味着比较不等于零是毫无意义的。
if ( a != 0 ); // Same as if ( a );
所以这留给我们:
if ( x ^ 0x1 );
与一个XOR。 XOR所做的实质上是检测不同的位。 所以,如果所有的位都是相同的,它将返回0.由于0是假的,唯一的时间将返回假是所有的位都是相同的。 所以如果参数是相同的,那么它是错误的,如果它们是不同的,就是不正确的,就像不等于运算符一样。
if ( x != 0x1 );
事实上,两者之间的唯一区别是!=
将返回0或1,而^
将返回任何数字,但结果的真实性总是相同的。 一个简单的方法来思考是。
(b != c) === !!(b ^ c) // for all b and c
最后的“简化”是将0x1
转换为1,因此您的语句相当于:
if ( x != 1 )
^是一个按位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的真值表:
aba xor b ---------------------------- 1 1 0 1 0 1 0 1 1 0 0 0
代码只是意味着
正如我看到迄今为止的答案错过了一个简单的规则来处理XOR
。 没有详细说明^
和0x
是什么意思( if
和!=
等),expression式0 != (x^1)
可以用以下事实进行修改: (a^a)==0
:
0 != (x^1) <=> [xor left and right side by 1] (0^1) != (x^1^1) <=> 1 != x
在这里, 可能使用的标准技术是重复一个习惯用法,因为它出现在周围的上下文中是为了清楚起见,而不是用一个在算术上更简单但是上下文无意义的习语replace它来混淆它。
周围的代码可能会频繁引用(x ^ 1)
,或者testing可能会问“如果第0位是相反的,这个位掩码是空的吗?
考虑到条件导致某些东西被encode()
,可能在上下文中,位0的默认状态已被其他因素反转,并且如果任何位偏离它们的默认值,我们只需要编码额外的信息(通常全零)。
如果你把这个expression置于语境之外,并且询问它的作用,你会忽视潜在的意图。 你也可以看一下编译器的汇编输出,看看它是否直接与1进行比较。