[docs] [issue29710] Incorrect representation caveat on bitwise operation docs

Nick Coghlan report at bugs.python.org
Tue May 16 08:59:22 EDT 2017


Nick Coghlan added the comment:

I think the simplest fix to make the docs "not wrong" would be to just delete the part in parentheses.

Beyond that, I'm not quite sure how to concisely describe the actual behaviour, but I think the mention of "2's complement" isn't especially helpful in its current form, since we don't give a clear sense of how the translation from an arbitrary length integer to a suitable 2's complement form is handled.

For `~n`, the most concise explanation is the arithmetic equivalent: it is always implemented as `-(n+1)`

Similarly, for `x << n` and `x >> n`, they're now exactly equivalent to `x * 2 ** n` and `x // 2 ** n` without any overflow checking or internal representation qualification (as even in Python 2.x, left-shift will automatically promote to a long when needed)

For `x | y` and `x & y`, things are a little more subtle, since that's where the internal 2's complement representation comes into play, but you can't just write out the formal definition of 2's complement at the Python level and get the same answer as is given by the binary operators:

>>> -5 & 5
1
>>> -5 | 5
-1

>>> (~-5 + 1) & 5 # Effectively '5 & 5'
5
>>> (~-5 + 1) | 5 # Effectively '5 | 5'
5

>>> -5 | (~5+1) # Effectively '-5 & -5'
-5
>>> -5 & (~5+1) # Effectively '-5 | -5'
-5


The problem here is that the sign bits of the operands matter a great deal, since they affect the sign expansion in the conversion to the 2's complement form, but that detail gets lost if the conversion is done prior to the bitwise binary operator invocation.

One way to get the same results as the interpreter level algorithms is to use a 2's complement bit length of `1 + max(x.bit_length(), y.bit_length()`, so the equivalent operations become:

>>> bin(0b1011 & 0b0101) # -5 & 5 -> 1 in 4 bit 2's complement
'0b1'
>>> bin(0b1011 | 0b0101) # -5 | 5 -> -1 in 4 bit 2's complement
'0b1111'

So perhaps a helpful change to make would be to move the note about negative numbers to a numbered footnote in the table, and state that the bitwise binary operations are semantically equivalent to calculations using two's complement in a bit-width of `1 + max(x.bit_length(), y.bit_length()`.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue29710>
_______________________________________


More information about the docs mailing list