What does (x ^ 0x1) != 0 mean?

C++CBit ManipulationBitmask

C++ Problem Overview


I came across the following code snippet

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

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

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

  • ^ is the bitwise [XOR][1] 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. [1]: http://en.wikipedia.org/wiki/Exclusive_or

Solution 3 - C++

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

Solution 4 - C++

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 )

Solution 5 - C++

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

Solution 6 - C++

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.

Solution 7 - C++

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.

Solution 8 - C++

^ 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.

Solution 9 - C++

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.

Solution 10 - C++

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?

Solution 11 - C++

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.

Solution 12 - C++

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.

Solution 13 - C++

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

Solution 14 - C++

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 )

Solution 15 - C++

^ is a [bitwise XOR][1] 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 [1]: http://en.wikipedia.org/wiki/Bitwise_operation#XOR

Solution 16 - C++

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.

Solution 17 - C++

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKodeWarriorView Question on Stackoverflow
Solution 1 - C++Paul RView Answer on Stackoverflow
Solution 2 - C++Violet GiraffeView Answer on Stackoverflow
Solution 3 - C++jwaliszkoView Answer on Stackoverflow
Solution 4 - C++Vlad from MoscowView Answer on Stackoverflow
Solution 5 - C++Ferenc DeakView Answer on Stackoverflow
Solution 6 - C++David HeffernanView Answer on Stackoverflow
Solution 7 - C++PaulView Answer on Stackoverflow
Solution 8 - C++ChinnaView Answer on Stackoverflow
Solution 9 - C++undefinedView Answer on Stackoverflow
Solution 10 - C++ChuckCottrillView Answer on Stackoverflow
Solution 11 - C++user541686View Answer on Stackoverflow
Solution 12 - C++Ed StaubView Answer on Stackoverflow
Solution 13 - C++Igrek.View Answer on Stackoverflow
Solution 14 - C++Kevin CoxView Answer on Stackoverflow
Solution 15 - C++akbar aliView Answer on Stackoverflow
Solution 16 - C++sh1View Answer on Stackoverflow
Solution 17 - C++Serge RogatchView Answer on Stackoverflow