(x ^ 0x1)!= 0是什么意思?

Kod*_*ior 183 c c++ bit-manipulation bitmask

我遇到了以下代码段

if( 0 != ( x ^ 0x1 ) )
     encode( x, m );
Run Code Online (Sandbox Code Playgroud)

什么x ^ 0x1意思?这是一些标准技术吗?

Pau*_*l R 277

XOR运算(x ^ 0x1)将位0反转.因此表达式实际上意味着:如果x的位0为0,或者x的任何其他位为1,则表达式为真.

相反,如果x == 1,则表达式为false.

因此测试与以下相同:

if (x != 1)
Run Code Online (Sandbox Code Playgroud)

因此(可以说)不必要地混淆了.

  • 不必要的混淆?难道你不知道我们的工作是混淆代码.如果我们编写简单的代码,任何人都可以理解,为什么,我们在世界上的立场的宗教神圣性会在哪里?我们突然像其他人一样成为普通工人.混淆本身就是必要的. (115认同)
  • @TheThom的照片уят (82认同)
  • @Spook:它不只是测试一个单位标志 - 它正在测试x的整个宽度.如果你只想测试一个比特,那么有更清晰的习语,比如使用按位AND. (40认同)
  • 嘿,你不知道背景.如果x是某种位标志,那么现在写IMO实际上比使用!=运算符更清晰. (39认同)
  • 实际上Spook是对的.测试(x!= 1)不相等.代码可以是C++(在C++中,^可以是执行任何操作的运算符).所以你不知道上下文,@ Spook是对的. (31认同)
  • @ xryl669然后应该与负责的开发人员一起删除代码.错误使用运算符会使代码难以阅读和维护.运算符^表现得像开发人员期望的那样(XOR),或者它会导致意外行为,正如您从响应/注释中看到的那样(每个人都认为它是异或). (7认同)
  • @larsmans我不想检查是否只设置了一个标志.我想检查第0个标志是*不*设置*和*任何其他是. (6认同)
  • @Spook不是这样.这是一个平等的考验. (5认同)
  • @Spook:即便如此,测试整个链的相等性比执行XOR更容易理解,因此在==的情况下使用XOR是不好的做法. (5认同)
  • @TheThom,你一定住在岩石下.程序员早已过时; 自从互联网起飞以及个人电脑无处不在以来.这些天,由于4GL(以及错误的5GL),每个人和他们的狗都是"程序员". (3认同)
  • @PaulR,可能值得一提的是,XOR操作反转了*在另一个参数*中所有的位,在这种情况下仅发生在位0.如果读出上下文,可能会有点误导 (2认同)
  • @EJP,你错了.在两个参数中关闭的位将在结果中关闭,这是一个反转?无论如何,当一个参数是一个掩码时,更自然地看一下对另一个参数的影响,这正是切换(也就是反转)掩码中的位. (2认同)

Vio*_*ffe 78

  • ^是按位XOR运算
  • 0x11十六进制表示法
  • x ^ 0x1将反转最后一位x(如果您不清楚,请参阅上面链接中的XOR真值表).

因此,(0 != ( x ^ 0x1 ))如果x大于1或者如果最后一位x为0 ,则条件将为真.这仅将x == 1作为条件为假的值.所以它相当于

if (x != 1)
Run Code Online (Sandbox Code Playgroud)

PS地狱的一种方式来实现这样一个简单的条件,我可能会补充说.不要那样做.如果您必须编写复杂的代码,请发表评论.我请求您.

  • 它不是'x == 0`; `4 ^ 0x1`为真,但`4 == 0`显然是假的. (7认同)
  • 等价预先假定`x`是一个整数类型.如果它是一个`float`或`double`,那么我相信表达式对于`1.0 <= x <2.0`会产生真.如果`x`是用户定义的类型,如果`x`是Yugo,袋鼠,着名作曲家的生日,或者任何与当前以美元计价的茶叶价格至少有三位数的数字,则表达式可以返回true.中国. (6认同)
  • "条件似乎等于`if(x == 0)`",它不等于`x!= 1`? (4认同)
  • @supercat对于`float` /`double`,没有`operator ^`. (4认同)

jwa*_*zko 49

这似乎是一个过于简单的解释,但如果有人想慢慢地通过它,它是在下面:

^是c,c ++和c#中的按位XOR运算符.

按位XOR采用相等长度的两个位模式,并对每对相应位执行逻辑异或运算.

异或是一种逻辑运算,只要两个输入不同(一个为真,另一个为假),则输出为真.

真值表一个XOR B:

a           b        a xor b
----------------------------
1           1           0
1           0           1
0           1           1
0           0           0
Run Code Online (Sandbox Code Playgroud)

那么让我们来说明0 == ( x ^ 0x1 )二进制级别的表达式:

             what? xxxxxxxx (8 bits)
               xor 00000001 (hex 0x1 or 0x01, decimal 1)    
             gives 00000000
---------------------------
the only answer is 00000001
Run Code Online (Sandbox Code Playgroud)

所以:

   0 == ( x ^ 0x1 )    =>    x == 1
   0 != ( x ^ 0x1 )    =>    x != 1
Run Code Online (Sandbox Code Playgroud)


Vla*_*cow 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;
Run Code Online (Sandbox Code Playgroud)

输出将是

0x0 ^ 0x0 = 0
0x0 ^ 0x1 = 1
0x1 ^ 0x0 = 1
0x1 ^ 0x1 = 0
Run Code Online (Sandbox Code Playgroud)

所以这个表达

0 != ( x ^ 0x1 )
Run Code Online (Sandbox Code Playgroud)

只有当x!= 0x1时才会相等.

它不会改变x本身.它仅检查x是否等于0或1.此rxpression可以更改为

if ( x != 0x1 )
Run Code Online (Sandbox Code Playgroud)


Fer*_*eak 19

它检查x实际上是不0x1... xor荷兰国际集团x0x1将导致0只要x0x1......这是大部分在汇编语言上使用的老把戏

  • @BitFiddlingCodeMonkey:否.如果XOR比某些本机级别相等测试快,则​​编译器将发出XOR以测试相等性.因此,XOR永远不会比优化编译器上的相等测试更快.编写快速代码的规则101是"不要尝试并帮助编译器.您最终只会制作在实践中速度较慢的不可读代码". (10认同)
  • 在远古时代进行手动装配优化(x86)如果我没记错,`xor`方法包含的机器代码较少,并且执行速度比相应的赋值更快...但是这个问题包含一个`xor`和一个比较所以我可能认为`!=`可能更快.但是,我不太确定,需要看一些编译器生成的程序集. (2认同)

Dav*_*nan 18

^操作是按位异或运算.并且0x1是数字1,写为十六进制常量.

因此,x ^ 0x1计算一个x与之相同的新值,但是最低有效位会被翻转.

代码只是将x与1进行比较,这是一种非常复杂和模糊的方式.


Pau*_*aul 11

xor(异或)运算符最常用于反转一个或多个位.操作是询问其中一个位是否为1,这导致下面的真值表(A和B是输入,Y是输出):

A    B    Y
0    0    0
0    1    1
1    0    1
1    1    0
Run Code Online (Sandbox Code Playgroud)

现在这个代码的目的似乎是检查最后一位是否为1,其他位是0,这等于if ( x != 1 ).这种模糊方法的原因可能是先前的位操作技术已被使用,并且可能在程序中的其他位置使用.


Chi*_*nna 8

^是按位xor operatorc.在你的情况下,x与x进行xor'ed,例如x值为10,那么10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11d条件变为true.

  • @PaulR如果你不在那里放一个`b`或者什么东西,怎么会有人知道什么是小数?什么是二进制? (6认同)

小智 8

按位测试似乎是故意的混淆,但如果底层数据是来自IBM大型机系统的公司数据,则可能只是编写代码以反映原始文档.IBM数据格式可以追溯到20世纪60年代,并经常将标志编码为一个字内的单个位以节省存储空间.在修改格式时,在现有记录的末尾添加了标志字节以保持向后兼容性.例如,SMF记录的文档可能会显示汇编语言代码,以测试单个记录中三个不同单词中的三个单独位,以确定数据是输入文件.我对TCP/IP内部的了解要少得多,但你也可以在那里找到位标志.


Chu*_*ill 7

运算符^是bitwise-xor(参见&,|).位对的结果是,

0 ^ 0 == 0
0 ^ 1 == 1
1 ^ 0 == 1
1 ^ 1 == 0
Run Code Online (Sandbox Code Playgroud)

那么表达,

( x ^ 0x1 )
Run Code Online (Sandbox Code Playgroud)

反转/翻转x的第0位(保持其他位不变).

考虑x是否可以具有除0x0和0x1之外的值?当x是单个位字段时,它只能有值0x0和0x1,但是当x是int(char/short/long/etc)时,bit0之外的位会影响表达式的结果.

给定的表达式允许bit0旁边的位影响结果,

if ( 0 != ( x ^ 0x1 ) )
Run Code Online (Sandbox Code Playgroud)

这与(更简单的)表达具有同等的真实性,

if ( x ^ 0x1 )
Run Code Online (Sandbox Code Playgroud)

请注意,此表达式仅检查bit0,

if( 0x1 & ( x ^ 0x1 ) )
Run Code Online (Sandbox Code Playgroud)

所以表达的表达式实际上是两个表达式检查相结合,

if( ( x & ~0x1 )  //look at all bits besides bit0
||  ( x ^ 0x1 ) ) //combine with the xor expression for bit0
Run Code Online (Sandbox Code Playgroud)

作者是否打算只检查bit0,并打算使用这个表达式,

if( 0x1 & ( x ^ 0x1 ) )
Run Code Online (Sandbox Code Playgroud)

或者作者是否打算将bit1-bitN和bit0的xor的值组合在一起?


Meh*_*dad 7

我正在添加一个新的答案,因为没有人真正解释如何直观地得到答案.

倒数+-.
倒数^^.

你是如何解决0 != x - 1x?你+ 1到双方:0 + 1 != x - 1 + 11 != x.
你是如何解决0 != x ^ 1x?你^ 1到双方:0 ^ 1 != x ^ 1 ^ 11 != x.


Ed *_*aub 6

我猜测还有其他位或位域值x,这是为了测试只设置低位.在上下文中,我猜这是默认的,因此m可以跳过这个和一些相关的编码(编码可能更昂贵),因为它们必须都是默认值,在构造函数中初始化或类似.

不知何故,解码器必须能够推断出这些值丢失了.如果它们位于某个结构的末尾,则可以通过length始终存在的值进行通信.