0

Small question, I'm trying to do the bitwise complement (NOT) of a signal that is 16-bit long. In Python from the documentation, I naively thought that doing the following would work:

~ x

To my surprise this returns negative numbers. I asked in a chat and they told me to use:

x ^ 65535

The thing that I still do not understand is why this works.

Why does this work?

4
  • 3
    Short answer: ~x inverts all the bits of x including its sign bit. x ^ 65536 (or x ^ 0xffff) inverts just the lower 16-bits of x. Commented Dec 27, 2015 at 4:11
  • 1
    @martineau - Almost! 0xffff is 65535. x ^ 65536 just adds 0x10000 to the number. Commented Dec 27, 2015 at 4:18
  • 1
    @martineau Thanks, I incorporated that into my answer. And that's proof that its probably better to use 0xffff - less chance of a bug ;) Commented Dec 27, 2015 at 4:18
  • @tdelaney: Good catch, I missed the char folks incorrectly told the OP to use 65536 instead of the correct value of 65535 (or 0xfff). Technically x ^ 65536 inverts the 17th bit of x, so if its value was 0x1, the result would be 0x10001 (or 35537) — which just happens to be the same as adding them together. Commented Dec 27, 2015 at 4:36

1 Answer 1

6

~x inverts all the bits of x including its sign bit. x ^ 65535 inverts just the lower 16-bits of x.

The ^ means bitwise XOR operation. The truth table for single bit a XOR b is:

a b | a^b
---------
0 0 | 0
0 1 | 1    <-
1 0 | 1
1 1 | 0    <-

XOR has an interesting property that a ^ 0 = a (identity) and a ^ 1 = not a (invert). You can see this in the <- lines in the above table.

So what x ^ 65535 (or x ^ 0xffff which is clearer) does is bitwise XOR the lower 16 bits with 16 ones to invert just the lower 16 bits (0xffff == 65535 is 16 ones). So for a 32 bit example:

       xxxx xxxx xxxx xxxx aaaa aaaa aaaa aaaa
xor    0000 0000 0000 0000 1111 1111 1111 1111
----------------------------------------------
       xxxx xxxx xxxx xxxx AAAA AAAA AAAA AAAA (where A is ~a)

The x's represent bits that remain the same in the input and result. The A's represent bits that have been inverted.

BTW: another way to do the same thing would have been:

~x & 0xffff
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.