10/14: Sought an explanation on "why"


#1

I'm a stubborn guy. So when Codecadamy tells me:

What this actually means to the computer is actually very complicated, so we're not going to get into it.

... I'm still gonna try and find out how it works, because otherwise it'll annoy the heck out of me. Turns out, this was a nice little trip down memory lane, to the days when I studied CS and digital electronics. The key issue here is something called Two's Complement (wikipedia). To quote that wiki-page a bit:

Two's complement is a mathematical operation on binary numbers, as well as a binary signed number representation based on this operation.

  • Let's say we're representing the number 1 in byte form: 00000001
  • If we perform a bitwise NOT, that becomes 11111110
  • Normally this would be interpreted as 255, were it not that:

In two's-complement representation, positive numbers are simply represented as themselves, and negative numbers are represented by the two's complement of their absolute value. [...] This system is the most common method of representing signed integers on computers.

And there in lies the rub! The ~ operator is not a bitwise "NOT", but a bitwise "COMPLEMENT" operator! The title and explanation of 10/14 are slightly misleading. The ~ explicitly tells Python to perform a NOT operation on a byte, into a two's complement representation. See also this article on Python.org.


#2

In simplest terms, using minimum bits required,

~1       #  110

Since it is a complement, as you observe, it has a sign bit, which is set to 1, meaning the number is negative. The complement of a positive number is a negative number.

-2

If x = 1 then ~x = -x-1 => -2.

~2     #  111  => -3

and so on, whence we spot the pattern. The negative of x is ~x + 1.

From this understanding we can see that there is no clear concept of NOT in Bitwise operations, unless we define it as toggling of all the bits. But this does not imply a complement since the result has no sign bit.

 > 255^128
=> 127            # 128 toggled is 127 in 8-bit representation
 > 255^10
=> 245            # 10 toggles to 245 in 8 bits
 > 255^170
=> 85

So NOT as a toggling operation is really an XOR operation with no sign bit.

Mark my words, I am not trying to be pedantic as much as work out the distinctions. I conclude that Bitwise doesn't have a NOT, any more than logical operations have a two's complement (which they don't). We have three operators that we can play with now.

 ~     # two's complement
 ^     # exclusive OR
NOT    # logical NOT to toggle a Boolean

That's what I get out of this. Comments welcome.


#3

Sounds like you're on top of things. Good show :smile:


#4

Thanks for bringing this up! I was wondering the same thing!