Python’s ** bitwise XOR** operator

`x ^ y`

performs *logical XOR*on each bit position on the binary representations of integers

`x`

and `y`

. Each output bit evaluates to 1 *if and only if*exactly one of the two input bits at the same position are 1. For example, the integer expression

`4 ^ 3`

is translated to the binary operation `0100 ^ 0011`

which results in `0111`

because for the last three positions exactly one bit is 1.As you go over the article, you can watch my explainer video here:

In this example, you apply the ** bitwise XOR **operator to two integers 32 and 16:

>>> 32 ^ 16 48

The expression `32 ^ 16`

operates on the bit representations `"0100000"`

(decimal 32) and `"0010000"`

(decimal 16) and performs ** bitwise XOR** resulting in binary

`"0110000"`

(decimal 48):First Operand `x` | 1 | 0 | 0 | 0 | 0 | 0 |

Second Operand `y` | 0 | 1 | 0 | 0 | 0 | 0 |

`x ^ y` | 1 | 1 | 0 | 0 | 0 | 0 |

Similarly, let’s have a look at a slightly modified example to showcase the ** bitwise XOR** operator:

>>> 31 ^ 15 16

You can see this in the following visualization:

First Operand `x` | 1 | 1 | 1 | 1 | 1 |

Second Operand `y` | 0 | 1 | 1 | 1 | 1 |

`x ^ y` | 1 | 0 | 0 | 0 | 0 |

The decimal representation of the bit sequence `"10000"`

is 16.

## Python Bitwise ^ Operator Example

Here’s the result of the ** bitwise XOR **operator

`x ^ y`

when applied to a couple of example integer operands `x`

and `y`

:x (int) | y (int) | x (binary) | y (binary) | x ^ y (binary) | x ^ y (int) |
---|---|---|---|---|---|

0 | 1 | 0 | 1 | 1 | 1 |

0 | 3 | 00 | 11 | 11 | 3 |

3 | 5 | 0011 | 0101 | 0110 | 6 |

33 | 129 | 000100001 | 010000001 | 010100000 | 160 |

15 | 7 | 01111 | 00111 | 01000 | 8 |

14 | 7 | 01110 | 00111 | 01001 | 9 |

You can see those examples in the following Python script:

>>> 0 ^ 1 1 >>> 0 ^ 3 3 >>> 3 ^ 5 6 >>> 33 ^ 129 160 >>> 15 ^ 7 8 >>> 14 ^ 7 9

Next, you’ll learn how to use the operator on negative integers. But first, you need to understand how negative integers are represented in the first place. This will boost your computer science skills, so keep reading! ?β?

## Representing Negative Integers in Binaries

Python uses so-called ** complementary binaries** to represent negative integers. The first bit of a complementary binary is the sign (0: positive, 1: negative). All remaining bits encode the number. You write a negative number

`-x`

as the bit pattern for `(x-1)`

and flip all bits from 1 to 0 and from 0 to 1 (complement).Here are two simple examples:

- To represent
`x = -1`

using 8 bits you first calculate`(1-1) = 0`

and then flip all bits to calculate`"11111111"`

. - To represent
`x = -10`

using 8 bits you first calculate`(10-1) = 9`

which is`"00001001"`

in binary format. Then, you complement all bits to determine the negative (complementary) binary`"11110110"`

.

Let’s use this knowledge in a couple of examples to showcase the working of the *bitwise XOR operator* on negative integers:

## Python Bitwise XOR ^ Examples on Negative Integers

Here’s the result of the *bitwise XOR* operator `x ^ y`

when applied to example negative integer operands `x`

and `y`

:

x (int) | y (int) | x (binary) | y (binary) | x ^ y (binary) | x ^ y (int) |
---|---|---|---|---|---|

0 | -1 | 00000000 | 11111111 | 11111111 | -1 |

0 | -3 | 00000000 | 11111101 | 11111101 | -3 |

-3 | -5 | 11111101 | 11111011 | 00000110 | 6 |

You can see those examples in the following script:

>>> 0 ^ -1 -1 >>> 0 ^ -3 -3 >>> -3 ^ -5 6

## Python Bitwise XOR List and Set

To perform a ** bitwise XOR** operation on all elements in a given

**, import the NumPy library using**

*list of integers*`import numpy as np`

and call `np.bitwise_xor.reduce(my_list)`

.Here’s an example:

import numpy as np my_list = [1, 2, 3, 4, 5] res = np.bitwise_xor.reduce(my_list) print(res) # 1

You can see the computation in the following table—the last row being the result of the* bitwise XOR* operation on all elements in the list `[1, 2, 3, 4, 5]`

that correspond to binaries `0001`

, `0010`

, `0011`

, `0100`

, and `0101`

.

Pos 0 | Pos 1 | Pos 2 | Pos 3 |
---|---|---|---|

0 | 0 | 0 | 1 |

0 | 0 | 1 | 0 |

0 | 0 | 1 | 1 |

0 | 1 | 0 | 0 |

0 | 1 | 0 | 1 |

0 | 0 | 0 | 1 |

To calculate this, you have to perform XOR along each given column, two rows at a time. If they’ve different bits, the intermediate result is 1, otherwise 0. Then, you use the result and compare it with the next row, and so on. The final result is 1.

Alternatively, if you want to perform a *bitwise XOR* on all elements in a set, you can use the same idea of importng the NumPy library using `import numpy as np`

and calling `np.bitwise_xor.reduce(my_set)`

.

import numpy as np my_set = [1, 2, 3, 4, 5] res = np.bitwise_xor.reduce(my_set) print(res) # 1

## Python Bitwise XOR Bool

The Boolean values `True`

and `False`

can be semantically represented by a single bit `1`

and `0`

. Thus, if you apply the bitwise XOR operation on two Boolean values using `x ^ y`

, the result is `True`

if and only if exactly one of the operands is `True`

.

Here are the four ways to apply the bitwise XOR operator to Boolean values:

>>> True ^ True False >>> True ^ False True >>> False ^ True True >>> False ^ False False

## Python Bitwise XOR Assignments (Equal)

The equal symbol after the *bitwise OR *operator (`x `

) performs `^`

= y** bitwise XOR assignment** operation. It calculates

*bitwise XOR*first and assigns the result to the variable

`x`

. The bitwise XOR assignment expression `x ``^`

= y

is syntactic sugar for the semantically identical `x = x ``^`

y

. The return value of the operator is `None`

but it updates the first operand with the result of the operation.Here you can see that the variable `x`

changes after applying the assignment operator:

>>> x = 1 >>> y = 2 >>> x ^= y >>> x 3 >>> y 2

Here’s the semantically identical version of this without the assignment operator:

>>> x = 1 >>> y = 2 >>> x = x ^ y >>> x 3 >>> y 2

## Python Bitwise XOR Overloading

You can define your own bitwise XOR operator on a custom class by overloading the `__xor__`

dunder method that allows the expression `x | y`

on your custom objects.

Here’s an example:

class Data: def __init__(self, data): self.data = data def __xor__(self, other): return Data(self.data ^ other.data) x = Data(3) y = Data(4) res = x ^ y print(res.data) # 7

**Note**: if you forget to overwrite the `__xor__`

method and still try to use the expression `x ^ `

y, Python will raise a `TypeError: unsupported operand type(s) for ^`

.

class Data: def __init__(self, data): self.data = data x = Data(3) y = Data(4) res = x ^ y print(res.data)

Output:

Traceback (most recent call last): File "C:\Users\xcent\Desktop\code.py", line 11, in res = x ^ y TypeError: unsupported operand type(s) for ^: 'Data' and 'Data'

To fix this `TypeError`

, simply define the `__xor__`

method as shown in the working example before.

## Bitwise Operators and Magic Methods

Bitwise operators perform operations on the binary (bit) representation of integers. The following table gives a short overview of all existing bitwise operators. Note that we also provide the binary representation `100`

for the decimal integer `4`

, and `101`

for the decimal integer `5`

as a comment in the right column.

Operator | Name | Description | Example |
---|---|---|---|

`x = 4, y = 5` | |||

& | Bitwise AND | Performs logical AND on a bit-by-bit basis | `x & y` |

| | Bitwise OR | Performs logical OR operation on a bit-by-bit basis | `x | y` |

~ | Bitwise NOT | Performs logical NOT on a bit-by-bit basis, inverting each bit so that 0 becomes 1 and 1 becomes 0. Same as `-x-1` . | `~x` |

^ | Bitwise XOR | Performs logical “exclusive or” operation on a bit-by-bit basis | `x ^ y` |

>> | Bitwise right shift | Shifts binary of left operand to the right by the number of positions specified in right operand | `x >> 2` |

<< | Bitwise left shift | Shifts binary of left operand to the left by the number of positions specified in right operand | `x << 2` |

Here’s a short overview of the Bitwise operators’ magic methods:

Bitwise Operator | Magic “Dunder” Method |
---|---|

`&` | `__and__(self, other)` |

`|` | `__or__(self, other)` |

`^` | `__xor__(self, other)` |

`~` | `__invert__(self)` |

`<<` | `__lshift__(self, other)` |

`>>` | `__rshift__(self, other)` |

Here’s an example of how to accomplish these bitwise operators on a custom class `Data`

. We marked this respective operator in the code:

class Data: def __init__(self, data): self.data = data def __and__(self, other): return Data(self.data & other.data) def __or__(self, other): return Data(self.data | other.data) def __xor__(self, other): return Data(self.data ^ other.data) def __invert__(self): return Data(~self.data) def __lshift__(self, other): return Data(self.data << other.data) def __rshift__(self, other): return Data(self.data >> other.data) x = 2 y = 3 print('Operands: \n', 'x =', x, '\n', 'y =', y) print() print('Bitwise AND: ', x & y) print('Bitwise OR: ', x | y) print('Bitwise XOR: ', x ^ y) print('Bitwise NOT: ', ~x) print('Bitwise LEFT-SHIFT: ', x << y) print('Bitwise RIGHT-SHIFT: ', x >> y)

The output is:

Operands: x = 2 y = 3 Bitwise AND: 2 Bitwise OR: 3 Bitwise XOR: 1 Bitwise NOT: -3 Bitwise LEFT-SHIFT: 16 Bitwise RIGHT-SHIFT: 0