What ~ already doing. The hard part is that Python has unlimited integers of length, so when you invert a number, this sign is expanded with - at least conceptually - an infinite number 1. This means you get negative numbers.
>>> bin(~0b101) '-0b110' >>> bin(~0b10101) '-0b10110'
To convert them to unsigned numbers, you need to decide how many bits you need. Perhaps you are working with 8-bit bytes. Then you could And them with a 1-bit byte:
>>> bin(~0b101 & 0xFF) '0b11111010' >>> bin(~0b10101 & 0xFF) '0b11101010'
Or, if you want to combine the exact bit length of the input numbers, your decision is reasonable. For efficiency, you can switch the exponent to shift left. And it may be more understandable to use ~ and & instead of ^ .
>>> bin(~a & ((1 << a.bit_length()) - 1)) '0b10' >>> bin(~b & ((1 << b.bit_length()) - 1)) '0b1010'
(I suspect that a hard encoding such as & 0xFFFF would be the right decision in practice. I cannot come up with a good real case of using bit_length() in the world for the answer.)
source share