def func():
print 'no early termination'
return 0
if __name__ == "__main__":
if 1 or func():
print 'finished'
The output:
finished
since the "1 or func()" terminates early without calling the func() because "1 or something" is always true. However, when switching to bitwise operator:
def func():
print 'no early termination'
return 0
if __name__ == "__main__":
if 1 | func():
print 'finished'
I get the output:
no early termination
finished
Why is that? this doesn't seem very efficient
Basically, you use them due to size and speed considerations. Bitwise operations are incredibly simple and thus usually faster than arithmetic operations. For example to get the green portion of an rgb value, the arithmetic approach is (rgb / 256) % 256 .
On simple low-cost processors, typically, bitwise operations are substantially faster than division, several times faster than multiplication, and sometimes significantly faster than addition.
Bitwise operators are used to change individual bits in an operand. A single byte of computer memory-when viewed as 8 bits-can signify the true/false status of 8 flags because each bit can be used as a boolean variable that can hold one of two values: true or false.
Not all programming languages support the use of bitwise operators. C, Java, JavaScript, Python and Visual Basic are among those that do. Because they allow greater precision and require fewer resources, bitwise operators can make some code faster and more efficient.
|
can't short-circuit because its value depends on its right-hand operand even if its left-hand operand is true. For example, in
x = 1 | 2
the value of x
can't be determined without knowing that there's a 2
on the right.
If we only cared about whether the if
branch was taken, Python might be able to analyze the structure of the program and optimize away the func
call, but the side-effects of func
must happen for the program to be correct. Python can't tell whether it matters to you that 'no early termination'
is printed; for all it knows, that's the signal that makes sure the dead man's switch won't release the neurotoxin.
(It's fine that the side-effects of func
don't occur with or
because or
is specifically designed to do that. Using or
tells the program you don't want the right-hand side evaluated if the left side is true.)
These are treated more like mathematical operations rather than logical operations. That's why the entire expression needs to be evaluated.
It's similar to saying
if (1 + 3)
It can just as easily be
if (1 - 3)
with logical operations.
You're not able to short-circuit the bitwise operations since they are not returning a simple truth value. Consider that 3 or 4
is 3
while 3|4
is 7. Without fully evaluating the expression, you will not be able to get the correct bitwise result.
With the logical operators, each side of the expression is a boolean that can be separately evaluated. Even if a particular language did not support short-circuiting, such an expression could be rewritten without the operator to achieve the same branching behavior. For example:
if 1 or func():
print 'finished'
could be rewritten:
if 1:
pass
elif func():
print 'finished'
In contrast, each side of the bitwise operator is an int, as is the result, which is then implicitly cast to boolean before being evaluated by the conditional. There is only one boolean expression, and thus nothing to short-circuit.
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