Binary negation in python
I can't seem to find logical negation of integers as an operator anywhere in Python.
Currently I'm using this:
def not_(x):
assert x in (0, 1)
return abs(1-x)
But I feel a开发者_开发知识库 little stupid. Isn't there a built-in operator for this? The logical negation (not
) returns a Boolean -- that's not really what I want. Is there a different operator, or a way to make not
return an integer, or am I stuck with this dodgy workaround?
You can use:
int(not x)
to convert the boolean to 0 or 1.
Did you mean:
int(not(x))
? Assuming that any non-zero integer value is true and 0 is false you'll always get integer 0 or 1 as a result.
If what you expect is to get 1 when input is 0, and 0 and when input is 1, then XOR is your friend. You need to XOR your value with 1:
negate = lambda x: x ^ True
negate(0)
Out: 1
negate(1)
Out: 0
negate(False)
Out: True
negate(True)
Out: False
If you are looking for Bitwise Not, then ~
is what you are looking for. However, it works in the two's complement form.
This will raise a KeyError if x is not in (0,1)
def not_(x):
return {1:0,0:1}[x]
The tuple version would also accept -1 if you don't add a check for it, but is probably faster
def not_(x):
return (1,0)[x]
$ python -m timeit "(1,0)[0]"
10000000 loops, best of 3: 0.0629 usec per loop
$ python -m timeit "(1,0)[1]"
10000000 loops, best of 3: 0.0646 usec per loop
$ python -m timeit "1^1"
10000000 loops, best of 3: 0.063 usec per loop
$ python -m timeit "1^0"
10000000 loops, best of 3: 0.0638 usec per loop
$ python -m timeit "int(not(0))"
1000000 loops, best of 3: 0.354 usec per loop
$ python -m timeit "int(not(1))"
1000000 loops, best of 3: 0.354 usec per loop
$ python -m timeit "{1:0,0:1}[0]"
1000000 loops, best of 3: 0.446 usec per loop
$ python -m timeit "{1:0,0:1}[1]"
1000000 loops, best of 3: 0.443 usec per loop
You can use not
but then convert result to integer.
int(False)
0
int(True)
1
I think Your approach is very good for two reasons:
- It is fast, clear and understandable
- It does error-checking
I assume that there cannot be such operator defined on the integers, because of the following problem: what to return if given value is not 0 or 1? Throw exception? Assume positive integers to mean 1? But negative integers?
Your approach defines concrete behaviour - accept only 0 or 1.
This can be easily done using some basic binary and string manipulation features in python
if x be an integer for which we want a bitwise negation, which is called x_bar(learned in digital class :))
>>> x_bar = x^int('1'*len(bin(x).split('b')[1]),2)
>>> bin(x_bar) #returns the binary string representation of integer 'x'
bin(int_value) function returns the binary string representation of any integer eg: '0b11011011'
xor operation is done with '1's'
精彩评论