Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Bitwise ~ Operator
#1
Can someone please explain why the following bitwise statement returns -11 and not -10? It does this with every number. Just negates it but adds 1 to the original number.

Thank you in advance.

num1 = 10 # Binary value = 1010

print(~num1) #Binary value 1011. Which is equal to -11
Output:
-11
Reply
#2
~ returns the complement of number i.e the number you get by switching each 1 for a 0 and each 0 for a 1. This is the same as -number - 1 (number=10; ~number -> -10-1 -> -11)
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#3
I am not sure I follow you. Can you elaborate on your response?

(Feb-02-2021, 05:44 PM)perfringo Wrote: ~ returns the complement of number i.e the number you get by switching each 1 for a 0 and each 0 for a 1. This is the same as -number - 1 (number=10; ~number -> -10-1 -> -11)
Reply
#4
Take a look at the wikipedia article on Two's complement.
Reply
#5
(Feb-02-2021, 06:44 PM)muzikman Wrote: I am not sure I follow you. Can you elaborate on your response?

There is Python wiki about this subject which explains both two's complement and ~ operator in that context: Bitwise operators
buran likes this post
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#6
The thing is, that the sign bit is also inverted.
To get a positive number, you can use the bitwise and operation.

x = 10
y = ~x & 0xFF # for 1 byte
z = ~x & 0xFFFF # for 2 byte
print(x, y, z)
Output:
10 245 65525
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#7
I studied this page and the Python bitwise page and this is what I understand:

(Feb-02-2021, 06:54 PM)bowlofred Wrote: Take a look at the wikipedia article on Two's complement.

In other strictly typed languages some have unsigned and signed integers. And, I know that a byte on windows is different than a byte on Linux. I do understand how we get the Two's Complement of a byte that is signed. e.g.

011111111 = 127. The two's complement of 127 is -128 because this number signed looks like 10000000 and has one more number than the unsigned.

127's compliment is -128 = 100000000.

3-bit signed numbers
011 = 3 because that is the unsigned part. 0 - 3. The signed part has 4 negative numbers which again, is one more than the unsigned.

So, -4 signed = 100 in binary. -1 signed is 111 in binary because it's the result of 3-4

What I don't understand is with 4 bit integers, how ~10 is equal to -11 using the same process. Using the ~10, it results in -11 in binary which is 1011. However, if we use the signed number process then, the largest possible negative value with 4 bits is -8. This is where I get confused.

Also, if I did ~128, it would give me -129. There aren't enough signed integers in one byte to arrive at the value -129.

Am I making this difficult? Am I missing something that is very easy?

Thank you, I really appreciate everyone's time and input.
Reply
#8
Python assumes it has "enough" bits for what it needs. Just add some more bits if necessary.

(Feb-05-2021, 03:56 PM)muzikman Wrote: What I don't understand is with 4 bit integers, how ~10 is equal to -11 using the same process. Using the ~10, it results in -11 in binary which is 1011. However, if we use the signed number process then, the largest possible negative value with 4 bits is -8. This is where I get confused.

Two's complement assumes we are doing signed arithmetic. And if you are, then 4 bits isn't enough to hold 10. b(1011) is -4, not +10. So you must have at least 5 bits. Let's instead assume we have 8 (you can add as many more as you want) Then 10 would be:

10 => 00001011
Flip the bits
00001011 => 11110100
add one
11110100 => 11110101
Convert back to decimal
11110101 => -11

The above holds as long as we have 5 or more bits. So the exact number doesn't matter, just as long as we can hold the number properly.

Quote:Also, if I did ~128, it would give me -129. There aren't enough signed integers in one byte to arrive at the value -129.

Then add more bits. You're not limited to 8 (or any particular number).
Reply
#9
What makes you think you are using a byte? I don't think Python has a byte type.

It has "bytes", but there are no bytes in bytes.
>>> x = (5).to_bytes(1, 'big')
>>> x
b'\x05'
>>> type(x)
<class 'bytes'>
>>> x[0]
5
>>> type(x[0])
<class 'int'>
bytes is a list of ints
Reply
#10
(Feb-05-2021, 04:56 PM)bowlofred Wrote: Python assumes it has "enough" bits for what it needs. Just add some more bits if necessary.

(Feb-05-2021, 03:56 PM)muzikman Wrote: What I don't understand is with 4 bit integers, how ~10 is equal to -11 using the same process. Using the ~10, it results in -11 in binary which is 1011. However, if we use the signed number process then, the largest possible negative value with 4 bits is -8. This is where I get confused.

Two's complement assumes we are doing signed arithmetic. And if you are, then 4 bits isn't enough to hold 10. b(1011) is -4, not +10. So you must have at least 5 bits. Let's instead assume we have 8 (you can add as many more as you want) Then 10 would be:

10 => 00001011
Flip the bits
00001011 => 11110100
add one
11110100 => 11110101
Convert back to decimal
11110101 => -11

The above holds as long as we have 5 or more bits. So the exact number doesn't matter, just as long as we can hold the number properly.

Quote:Also, if I did ~128, it would give me -129. There aren't enough signed integers in one byte to arrive at the value -129.

Then add more bits. You're not limited to 8 (or any particular number).

I totally get what you're saying and that is basically what I have concluded. Python does this so it's primitive data types maintain the same amount of storage across different platforms.

So, I need to negate everything but I don't even have to add 1.

0000 1010 = 10 decimal. -11 is reached by the following:

Negate everything by changing 1 to 0, 0 to 1 => 1111 0101

Because we are dealing with a signed number, the left most bit is -128. Now, you have simple addition because Everything after the left bit is positive, up until 127 if every bit is a 1.

-128 + 64 + 32 + 16 + 4 + 1 = -11

You don't even have to add one if you negate everything assuming the number is signed.

Do I have this correct?

Quote:10 => 00001011
Flip the bits
00001011 => 11110100
add one
11110100 => 11110101
Convert back to decimal
11110101 => -11
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Program demonstrates operations of bitwise operators without using bitwise operations ShawnYang 2 1,822 Aug-18-2021, 03:06 PM
Last Post: deanhystad
  Bitwise Slicing Peter_Truman 6 3,627 Aug-25-2020, 06:41 AM
Last Post: Peter_Truman
  not bitwise ~15 1885 3 2,573 Oct-30-2019, 03:49 AM
Last Post: 1885
  understanding exponential and bitwise operators srm 1 2,098 Jun-15-2019, 11:14 AM
Last Post: ThomasL

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020