Should be a simple question, but I'm unable to find an answer anywhere. The ~
operator in python is a documented as a bitwise inversion operator. Fine. I have noticed seemingly schizophrenic behavior though, to wit:
~True -> -2 ~1 -> -2 ~False -> -1 ~0 -> -1 ~numpy.array([True,False],dtype=int) -> array([-2,-1]) ~numpy.array([True,False],dtype=bool) -> array([False,True])
In the first 4 examples, I can see that python is implementing (as documented) ~x = -(x+1)
, with the input treated as an int even if it's boolean. Hence, for a scalar boolean, ~
is not treated as a logical negation. Not that the behavior is identical on a numpy array defined with boolean values by with an int type.
Why does ~
then work as a logical negation operator on a boolean array (Also notice: ~numpy.isfinite(numpy.inf) -> True
?)?
It is extremely annoying that I must use not()
on a scalar, but not()
won't work to negate an array. Then for an array, I must use ~
, but ~
won't work to negate a scalar...
We can also use the Tilde operator (~) also known as bitwise negation operator in computing to invert the given array. It takes the number n as binary number and “flips” all 0 bits to 1 and 1 to 0 to obtain the complement binary number.
The bitwise operator ~ (pronounced as tilde) is a complement operator. It takes one bit operand and returns its complement. If the operand is 1, it returns 0, and if it is 0, it returns 1.
Python's Tilde ~n operator is the bitwise negation operator: it takes the number n as binary number and “flips” all bits 0 to 1 and 1 to 0 to obtain the complement binary number. For example, the tilde operation ~1 becomes 0 and ~0 becomes 1 and ~101 becomes 010 .
not
is implemented through the __nonzero__
special method, which is required to return either True
or False
, so it can't give the required result. Instead the ~
operator is used, which is implemented through the __not__
special method. For the same reason, &
and |
are used in place of and
and or
.
PEP 335 aimed to allow overloading of boolean operators but was rejected because of excessive overhead (it would e.g. complicate if
statements). PEP 225 suggests a general syntax for "elementwise" operators, which would provide a more general solution, but has been deferred. It appears that the current situation, while awkward, is not painful enough to force change.
np.isfinite
when called on a scalar returns a value of type np.bool_
, not bool
. np.bool_
is also the type you get when extracting a scalar value from an array of bool dtype. If you use np.True_
and np.False_
in place of True
and False
you will get consistent behaviour under ~
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With