Why is that
>>> print(f"{-5 & 0b1111: 04b}")
1011
However,
>>> print(f"{-5 | 0b0000: 04b}")
-101
Moreover,
>>> print(f"{-5 | 0b1111: 04b}")
-001
It seems, that first -5 is converted to 2's compliment then operation is performed. Then, in case of '&' output is printed/interpreted as such, but for |
output is converted back to signed magnitude representation. Why is there such an asymmetry?
-5 in binary (two's complement) is ...111111111011. Python can handle arbitrary-precision integers and there's not really a nice way to print out an infinite string of preceding ones, so it represents negative binary numbers with a minus sign. (Well, we could argue about this maybe, but it is what it is.)
The bitwise and of something with a positive number (as in your first example) will always be positive because the preceeding zeros of the positive number will combine with anything to create preceeding zeros in the result.
The bitwise or of a negative number with anything (as in your other examples) is always negative because the preceeding ones of the negative number will combine with anything to create preceeding ones in the result.
The only difference you are seeing is the sign of the result. Negative results are always printed with a minus sign.