What does the caret (^) operator do?
Asked Answered
M

5

174

I ran across the caret operator in python today and trying it out, I got the following output:

>>> 8^3
11
>>> 8^4
12
>>> 8^1
9
>>> 8^0
8
>>> 7^1
6
>>> 7^2
5
>>> 7^7
0
>>> 7^8
15
>>> 9^1
8
>>> 16^1
17
>>> 15^1
14
>>>

It seems to be based on 8, so I'm guessing some sort of byte operation? I can't seem to find much about this searching sites other than it behaves oddly for floats, does anybody have a link to what this operator does or can you explain it here?

Meantime answered 16/3, 2010 at 0:21 Comment(8)
For integers, same thing it does in C. ^_-Arbiter
FYI, from the python shell, you can type help('^')Backache
-1: This is completely covered in the Python documentation and the included help function. Asking this question here is silly.Disinterest
Note that it doesn't behave oddly for floats (it just doesn't work with floats!). Also note that many people accidentally run into this while looking for **, the exponentiation operator.Synn
@seth: help('^') does nothing in my Python 2.6.1 (apple build). @S.Lott: do you mean this (docs.python.org/reference/…) when you're saying "completely covered"?. Seems a bit sparse for someone unfamiliar with the concept...Samara
@Mike Graham: that's actually where it came from. I saw the ** operator and thought, well I wonder what caret does then, and here we are :)Meantime
@ChristopheD, No, he didn't mean that page, which is about parsing Python, not he semantics of what ^ does. help('^') in the interactive interpretter should pull up the help explaining the arithmetic operators, which would have provided only the name "bitwise XOR", which would have been enough information to go on.Synn
I tried this in my interpreter (2.5.4) and got: >>> help('^') no Python documentation found for '^'Meantime
S
259

It's a bitwise XOR (exclusive OR).

It evaluates to True if and only if its arguments differ (one is True, the other is False).

To demonstrate:

>>> 0^0
0
>>> 1^1
0
>>> 1^0
1
>>> 0^1
1

To explain one of your own examples:

>>> 8^3
11

Think about it this way:

1000  # 8 (binary)
0011  # 3 (binary)
----  # APPLY XOR ('vertically')
1011  # result = 11 (binary)
Samara answered 16/3, 2010 at 0:23 Comment(3)
A slightly more illustrative example might include both numbers having 1 in the same bit to make it clear that 1 xor 1 = 0.Synn
I wanted to add, you can do binary numbers by typing 0bX where X is your binary. 0b0001, 0b0010, etc. So, 0b1101 ^ 0b1110 would give you 0b0011 (or 3).Antigen
I think "It results to true if one (and only one) of the operands (evaluates to) true." is not exact, it what would be the definition of a boolean xorFacet
I
51

It invokes the __xor__() or __rxor__() method of the object as needed, which for integer types does a bitwise exclusive-or.

Ilarrold answered 16/3, 2010 at 0:37 Comment(0)
N
16

It's a bit-by-bit exclusive-or. Binary bitwise operators are documented in chapter 5 of the Python Language Reference.

Neese answered 16/3, 2010 at 0:23 Comment(0)
Y
13

Generally speaking, the symbol ^ is an infix version of the __xor__ or __rxor__ methods. Whatever data types are placed to the right and left of the symbol must implement this function in a compatible way. For integers, it is the common XOR operation, but for example there is not a built-in definition of the function for type float with type int:

In [12]: 3 ^ 4
Out[12]: 7

In [13]: 3.3 ^ 4
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-13-858cc886783d> in <module>()
----> 1 3.3 ^ 4

TypeError: unsupported operand type(s) for ^: 'float' and 'int'

One neat thing about Python is that you can override this behavior in a class of your own. For example, in some languages the ^ symbol means exponentiation. You could do that this way, just as one example:

class Foo(float):
    def __xor__(self, other):
        return self ** other

Then something like this will work, and now, for instances of Foo only, the ^ symbol will mean exponentiation.

In [16]: x = Foo(3)

In [17]: x
Out[17]: 3.0

In [18]: x ^ 4
Out[18]: 81.0
Yukikoyukio answered 18/10, 2013 at 13:37 Comment(5)
woah, was that even possible? and could we probably change how the + operator works too?Superfine
Yes, this is how the + symbol is able to do one kind of action for list (concatenation) while doing another kind of action (mathematical addition) for numeric types. In that case, you would override the __add__ or __radd__ methods in your class.Yukikoyukio
As a side note, the __r*__ version of these (like __rxor__ or __radd__) will be invoked from the argument appearing on the right hand side of the infix symbol, and only if the call to the function for the left hand symbol doesn't work. You can think of it like try: left_hand_symbol.__xor__(right_hand_symbol); except: right_hand_symbol.__rxor__(left_hand_symbol), but xor can be replaced by any of the available infix operators in the Python Data Model.Yukikoyukio
So that means I can craft my own operator which allows int concatenation with strings? man, python is way complex than I thoughtSuperfine
Side note, seeing as Python defines this as an xor operation and the method name has "xor" in it, I would consider it a poor design choice to make that method do something not related to xor like exponentiation. I think it's a good illustrative example of how it simply calls the __xor__ method, but to do that for real would be bad practice.Footprint
P
8

When you use the ^ operator, behind the curtains the method __xor__ is called.

a^b is equivalent to a.__xor__(b).

Also, a ^= b is equivalent to a = a.__ixor__(b) (where __xor__ is used as a fallback when __ixor__ is implicitly called via using ^= but does not exist).

In principle, what __xor__ does is completely up to its implementation. Common use cases in Python are:

  • Symmetric Difference of sets (all elements present in exactly one of two sets)

Demo:

>>> a = {1, 2, 3}
>>> b = {1, 4, 5}
>>> a^b
{2, 3, 4, 5}
>>> a.symmetric_difference(b)
{2, 3, 4, 5}
  • Bitwise Non-Equal for the bits of two integers

Demo:

>>> a = 5
>>> b = 6
>>> a^b
3

Explanation:

    101 (5 decimal)
XOR 110 (6 decimal)
-------------------
    011 (3 decimal)
Pilewort answered 19/11, 2018 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.