182

I came across the following code snippet

if( 0 != ( x ^ 0x1 ) )
     encode( x, m );

What does x ^ 0x1 mean? Is this some standard technique?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
KodeWarrior
  • 3,538
  • 3
  • 26
  • 40
  • 98
    [Code obfuscation](http://en.wikipedia.org/wiki/Obfuscation_%28software%29) is quite standard. – raina77ow Dec 19 '13 at 10:51
  • Few days ago I also got some similar situation http://stackoverflow.com/questions/19730348/why-101-is-11-in-c –  Dec 19 '13 at 13:59
  • 48
    This can be solved with the same approach as a "normal" equation: ```0 != (x ^ 1)``` → xor both sides by 1 → ```(0 ^ 1) != (x ^ 1 ^ 1)``` → simplify → ```1 != x``` – Score_Under Dec 19 '13 at 14:19
  • 4
    I don't see how `if (1 != x)` is hard to write. – Adriano Varoli Piazza Dec 19 '13 at 21:34
  • 12
    Various comments, first by @Spook, clearly point out that the `type` of `x` is not given - hence we do not know this is an integer in this C++ tagged problem. Sure, if this is C or `x` is an integer, the answer is easy, but that is not a given and the possibility of overloading `operator ^` exists. – chux - Reinstate Monica Dec 20 '13 at 02:47
  • 11
    I don't see how this gets so many upvotes... – laike9m Dec 25 '13 at 03:24

17 Answers17

277

The XOR operation (x ^ 0x1) inverts bit 0. So the expression effectively means: if bit 0 of x is 0, or any other bit of x is 1, then the expression is true.

Conversely the expression is false if x == 1.

So the test is the same as:

if (x != 1)

and is therefore (arguably) unnecessarily obfuscated.

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • 40
    Hey, you don't know the context. If x is some kind of bit flag, it is IMO actually more clear to write it as it is now than using the != operator. – Spook Dec 19 '13 at 10:57
  • 5
    @Spook Not so. It's an equality test. – David Heffernan Dec 19 '13 at 10:59
  • 40
    @Spook: it's not just testing a single bit flag though - it's testing the entire width of x. If you just want to test a single bit then there are clearer idioms, such as using a bitwise AND. – Paul R Dec 19 '13 at 10:59
  • 6
    @larsmans I don't want to check if only one flag is set. I want to check if 0th flag is *not* set *and* any other is. – Spook Dec 19 '13 at 11:02
  • 115
    Unnecessarily obfuscated? Don't you know that it's our job to obfuscate code. If we wrote simple code that anyone could understand, why, where would go the religious sanctity of our positions in the world? We'd suddenly be common workers like everyone else. Obfuscation is inherently necessary. – Thom Dec 19 '13 at 14:27
  • 5
    @Spook: Even then, testing the entire chain for equality is more readable and immediately understandable than doing an XOR, so it's bad practice to use an XOR when an == will do. – Matt Dec 19 '13 at 14:49
  • 31
    Actually Spook is right. The test (x != 1) is not equivalent. The code can be C++ (and in C++, ^ can be an operator that does anything). So you don't know the context, @Spook is right. – xryl669 Dec 19 '13 at 18:33
  • 82
    @TheThom уєт уσυ ωяιтє ιи ¢ℓєαя тєχт – bobobobo Dec 19 '13 at 20:05
  • 3
    @TheThom, you must be living under a rock. Programmers have long since become obsolete; ever since the Internet took off and personal computers became ubiquitous. These days, everybody and their dog are “programmers” thanks to 4GLs (and misnomered 5GLs). – Synetech Dec 19 '13 at 20:54
  • This may not be identical to the test (x!=1), but it should be. – Dave Dec 19 '13 at 21:06
  • Would this affect little/big endian systems differently? – txtechhelp Dec 19 '13 at 21:50
  • @txtechhelp: no, there is nothing endian-specific in the test. – Paul R Dec 19 '13 at 21:52
  • @txtechhelp: no, because 0x1 will be the same endianness. – Violet Giraffe Dec 20 '13 at 08:47
  • 7
    @xryl669 then the code should be removed along with the responsible developer. Miss use of operators makes code hard to read and maintain . Either the operator^ behaves like developers expect it to (XOR) or it leads to unexpected behavior as you can see from the responses/comments (every one assumes it is XOR). – josefx Dec 21 '13 at 14:15
  • 2
    @PaulR, may be worth mentioning that the XOR operation inverts *all the bits that are on in the other argument*, which happens in this case to be bit 0 only. It could be a little misleading if read out of context – Leeor May 03 '14 at 08:42
  • @Leeor No it doesn't. It inverts all the bits that are on in both arguments, or off in both arguments, and leaves the bits arhat are on in one and not the other. – user207421 Apr 29 '15 at 12:23
  • 2
    @EJP, you're wrong. bits that are off in both argument will be off in the result, how is that an inversion? Anyway, when one argument is a mask, it's more natural to look at the impact on the other argument, which is exactly to toggle (a.k.a invert) the bits that are on in the mask. – Leeor Apr 29 '15 at 12:38
79
  • ^ is the bitwise XOR operation
  • 0x1 is 1 in hex notation
  • x ^ 0x1 will invert the last bit of x (refer to the XOR truth table in the link above if that's not clear to you).

So, the condition (0 != ( x ^ 0x1 )) will be true if x is greater than 1 or if the last bit of x is 0. Which only leaves x==1 as a value at which the condition will be false. So it is equivalent to

if (x != 1)

P. S. Hell of a way to implement such a simple condition, I might add. Don't do that. And if you must write complicated code, leave a comment. I beg of you.

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335
  • 7
    It's not `x==0`; `4 ^ 0x1` is true, but `4==0` is obviously false. – Fred Foo Dec 19 '13 at 10:54
  • 4
    "condition seems to be equal to `if (x == 0)`", doesn't it equal to `x != 1`? – Andrew-Dufresne Dec 19 '13 at 10:56
  • @Andrew-Dufresne: never mind, I made a mistake there. Edited it out. – Violet Giraffe Dec 19 '13 at 10:58
  • 6
    The equivalence presupposes that `x` is an integral type. If it's a `float` or `double`, then I believe the expression would yield true for `1.0 <= x < 2.0`. And if `x` is a user-defined type, the expression could return true if `x` is a Yugo, kangaroo, famous composer's birthday, or any number which shares at least three digits with the current dollar-denominated price of tea in China. – supercat Dec 19 '13 at 18:04
  • 4
    @supercat There is no `operator^` for `float`/`double`. – fluffy Dec 19 '13 at 23:49
  • @fluffy: True, but I believe that in C values of `float` or `double` implicitly convert to `int`, do they not? – supercat Dec 19 '13 at 23:59
  • 1
    @supercat: When a conversion from floating-point to integer is called for, the conversion is implicit (doesn't require cast syntax). But no conversion is triggered by bitwise operators, they simply fail for floating-point types. – Ben Voigt Dec 20 '13 at 05:37
  • @BenVoigt: Okay, thanks. It would still be possible for user-defined types to overload `^` (and for that matter `==`) in various interesting fashions. – supercat Dec 20 '13 at 06:01
  • @supercat You can't define new `operator` functions for fundamental types, for two reasons: 1) it's not a function, and 2) you can't just create a new `operator` for any type that conflicts with an existing definition anyway, because otherwise you run into all sorts of crazy with "which one do you mean?" at link time. – fluffy Dec 21 '13 at 05:17
  • @fluffy: I thought C++ operator types were bound to the left operand, so one couldn't define a new meaning for `1^q`, but could for `q^1`. Am I misremembering? – supercat Dec 21 '13 at 07:28
  • @supercat Well, that depends on what type `q` is, obviously. You can certainly do a `MyType::operator^(float)` or similar. – fluffy Dec 21 '13 at 22:25
49

This may seem as oversimplified explanation, but if someone would like to go through it slowly it is below:

^ is a bitwise XOR operator in c, c++ and c#.

A bitwise XOR takes two bit patterns of equal length and performs the logical exclusive OR operation on each pair of corresponding bits.

Exclusive OR is a logical operation that outputs true whenever both inputs differ (one is true, the other is false).

The truth table of a xor b:

a           b        a xor b
----------------------------
1           1           0
1           0           1
0           1           1
0           0           0

So let's illustrate the 0 == ( x ^ 0x1 ) expression on binary level:

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

so:

   0 == ( x ^ 0x1 )    =>    x == 1
   0 != ( x ^ 0x1 )    =>    x != 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
jwaliszko
  • 16,942
  • 22
  • 92
  • 158
34

It is exclusive OR (XOR) operator. To understand how it works you can run this simple code

    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;

The output will be

0x0 ^ 0x0 = 0
0x0 ^ 0x1 = 1
0x1 ^ 0x0 = 1
0x1 ^ 0x1 = 0

So this expression

0 != ( x ^ 0x1 )

will be equal true only when x != 0x1.

It does not change x itself. It only checks whether x is equal to 0 or 1. this rxpression could be changed to

if ( x != 0x1 )
Shoe
  • 74,840
  • 36
  • 166
  • 272
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
19

It checks that x is actually not 0x1... xoring x with 0x1 will result in 0 only if x is 0x1 ... this is an old trick mostly used in assembly language

Ferenc Deak
  • 34,348
  • 17
  • 99
  • 167
  • Is this faster than `!= 1`? – Fiddling Bits Dec 19 '13 at 10:58
  • 2
    in ancient times while doing manual assembly optimizations (x86) if I remember correctly the `xor` approach contained less machine code and was executed faster than the corresponding assignment to `0`... however this question contains an `xor` AND a comparison, so I might think that the `!=` might be faster. I'm not so sure however, would need to see some compiler generated assembly. – Ferenc Deak Dec 19 '13 at 11:53
  • 10
    @BitFiddlingCodeMonkey: No. If XOR was faster than some native level equality test, your compiler would emit XORs to test for equality. Hence, XORs are never faster than equality tests on optimizing compilers. Rule 101 of writing fast code is "don't try and help the compiler. You'll only end up making unreadable code that's slower in practice". – Matt Dec 19 '13 at 14:45
  • @fritzone IIRC, the XOR tricks had more to do with saving registers, saving a register load b/c the literal could be encoded directly in the OP in some cases, and some subtle differences with status flags (but most of my assembly was on 68k and DSP). – mpdonadio Dec 19 '13 at 17:28
  • 1
    @MPD: Normally it's to do with clearing a register (at least on 386+). *xor eax, eax* sets eax to zero in two bytes, but *mov eax, 0* takes three or six bytes (depending on the encoding), and takes slightly longer to decode than the *xor* form. – Matt Dec 20 '13 at 11:02
18

The ^ operator is bitwise xor. And 0x1 is the number 1, written as a hexadecimal constant.

So, x ^ 0x1 evaluates to a new value that is the same as x, but with the least significant bit flipped.

The code does nothing more than compare x with 1, in a very convoluted and obscure fashion.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
11

The xor (exclusive or) operator is most commonly used to invert one or more bits. The operation is to ask if excactly one of the bits are one, this leads to the following truth table (A and B are inputs, Y is output):

A    B    Y
0    0    0
0    1    1
1    0    1
1    1    0

Now the purpose of this code seems to be to check if excatly the last bit is 1, and the others are 0, this equals if ( x != 1 ). The reason for this obscure method might be that prior bit manipulation techniques have been used and perhaps is used other places in the program.

Paul
  • 370
  • 3
  • 12
8

^ is bitwise xor operator in c. In your case x is xor'ed with 1. for example x has the value 10, then 10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11d so condition becomes true.

Chinna
  • 3,930
  • 4
  • 25
  • 55
8

The bitwise test seems to be a deliberate obfuscation, but if the underlying data is corporate data from an IBM mainframe system it may simply be that the code was written to reflect the original documentation. IBM data formats go back to the 1960's and frequently encode flags as single bits within a word to save storage. As the formats were modified, flag bytes were added at the end of the existing records to maintain backwards compatibility. The documentation for an SMF record, for example, might show the assembly language code to test three individual bits within three different words in a single record to decide that the data was an input file. I know much less about TCP/IP internals, but you may find bit flags there, as well.

undefined
  • 181
  • 3
  • 6
7

The operator ^ is the bitwise-xor (see &, | ). The result for a bit pair is,

0 ^ 0 == 0
0 ^ 1 == 1
1 ^ 0 == 1
1 ^ 1 == 0

So the expression,

( x ^ 0x1 )

inverts/flips the 0th bit of x (leaving other bits unchanged).

Consider whether x can have values besides 0x0 and 0x1? When x is a single bit field, it can have only values 0x0 and 0x1, but when x is an int (char/short/long/etc), bits besides bit0 can affect the result of the expression.

The expression as given allows bits beside bit0 to affect the result,

if ( 0 != ( x ^ 0x1 ) )

Which has equivalent truthiness as this (simpler) expression,

if ( x ^ 0x1 )

Note that this expression would examine only bit0,

if( 0x1 & ( x ^ 0x1 ) )

So the expression as presented is really combining two expression checks,

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

Did the author intend to only check bit0, and have meant to use this expression,

if( 0x1 & ( x ^ 0x1 ) )

Or did the author intend to comingle the values for bit1-bitN and the xor of bit0?

ChuckCottrill
  • 4,360
  • 2
  • 24
  • 42
7

I'm adding a new answer because no one really explained how to get the answer intuitively.

The inverse of + is -.
The inverse of ^ is ^.

How do you solve 0 != x - 1 for x? You + 1 to both sides: 0 + 1 != x - 1 + 11 != x.
How do you solve 0 != x ^ 1 for x? You ^ 1 to both sides: 0 ^ 1 != x ^ 1 ^ 11 != x.

user541686
  • 205,094
  • 128
  • 528
  • 886
6

I'd guess that there are other bits or bit-field values in x, and this is intended to test that only the low-order bit is set. In the context, I'd guess that this is the default, and that therefore encoding of this and some related m (probably more expensive to encode) can be skipped, because they must both be the default value, initialized in a constructor or similar.

Somehow the decoder must be able to infer that these values are missing. If they are at the end of some structure, it may be communicated via a length value that's always present.

Ed Staub
  • 15,480
  • 3
  • 61
  • 91
4

The XOR is useful in C# flag enum. To remove single flag from enum value it is necessary to use xor operator (reference here)

Example:

[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
Mr.Y.
  • 180
  • 10
  • BUT the question is about C++, not C# – theDmi Dec 19 '13 at 13:25
  • @theDmi: BUT ALSO about bit manipulation and bitmask. Flag enum in C# is definitely about bitmask. – Mr.Y. Dec 19 '13 at 13:29
  • Plus it can be useful in C++ as well. See : [Stack 1](http://stackoverflow.com/questions/1448396/how-to-use-enums-as-flags-in-c) and [Stack 2](http://stackoverflow.com/questions/7366458/c-checking-enum-flags) – Mr.Y. Dec 19 '13 at 13:35
  • This answer doesn't seem to have anything to do with the original question, other than some discussion of the bitwise XOR operator ? – Paul R Apr 20 '17 at 07:55
4

There are a lot of good answers but I like to think of it in a simpler way.

if ( 0 != ( x ^ 0x1 ) );

First of all. An if statement is only false if the argument is zero. This means that comparing not equal to zero is pointless.

if ( a != 0 );
// Same as
if ( a );

So that leaves us with:

if ( x ^ 0x1 );

An XOR with one. What an XOR does is essentially detect bits that are different. So, if all the bits are the same it will return 0. Since 0 is false, the only time it will return false is if all of the bits are the same. So it will be false if the arguments are the same, true if they are different...just like the not equal to operator.

if ( x != 0x1 );

If fact, the only difference between the two is that != will return 0 or 1, while ^ will return any number, but the truthyness of the result will always be the same. An easy way to think about it is.

(b != c) === !!(b ^ c) // for all b and c

The final "simplification" is converting 0x1 to decimal which is 1. Therefore your statement is equivalent to:

if ( x != 1 )
Kevin Cox
  • 3,080
  • 1
  • 32
  • 32
1

^ is a bitwise XOR operator

If x = 1

          00000001   (x)       (decimal 1)
          00000001   (0x1)     (decimal 1)
XOR       00000000   (0x0)     (decimal 0)

here 0 == ( x ^ 0x1 )

If x = 0

          00000000   (x)       (decimal 0)
          00000001   (0x1)     (decimal 1)
XOR       00000001   (0x1)     (decimal 0)

here 0 != ( x ^ 0x1 )

The truth table of a xor b:

a           b        a xor b
----------------------------
1           1           0
1           0           1
0           1           1
0           0           0

The code simply means

akbar ali
  • 427
  • 2
  • 6
1

The standard technique that might be being used, here, is to repeat an idiom as it appears in surrounding context for clarity, rather than to obfuscate it by replacing it with an idiom that is arithmetically simpler but contextually meaningless.

The surrounding code may make frequent reference to (x ^ 1), or the test may be asking "if bit 0 was the other way around, would this bit-mask be empty?".

Given that the condition causes something to be encode()ed, it may be that in context the default state of bit 0 has been inverted by other factors, and we need only encode extra information if any of the bits deviate from their default (normally all-zero).

If you take the expression out of context and ask what it does, you overlook the underlying intention. You might just as well look at the assembly output from the compiler and see that it simply does a direct equality comparison with 1.

sh1
  • 4,324
  • 17
  • 30
0

As I see the answers so far miss a simple rule for handling XORs. Without going into details what ^ and 0x mean (and if, and != etc), the expression 0 != (x^1) can be reworked as follows using the fact that (a^a)==0:

0 != (x^1) <=> [xor left and right side by 1]
(0^1) != (x^1^1) <=>
1 != x
Serge Rogatch
  • 13,865
  • 7
  • 86
  • 158