Posts: 138
Threads: 26
Joined: Nov 2020
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
Posts: 1,950
Threads: 8
Joined: Jun 2018
Feb-02-2021, 05:44 PM
(This post was last modified: Feb-02-2021, 05:44 PM by perfringo.)
~ 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.
Posts: 138
Threads: 26
Joined: Nov 2020
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)
Posts: 1,583
Threads: 3
Joined: Mar 2020
Take a look at the wikipedia article on Two's complement.
Posts: 1,950
Threads: 8
Joined: Jun 2018
(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
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.
Posts: 2,125
Threads: 11
Joined: May 2017
Feb-04-2021, 08:43 AM
(This post was last modified: Feb-04-2021, 08:43 AM by DeaD_EyE.)
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
Posts: 138
Threads: 26
Joined: Nov 2020
Feb-05-2021, 03:56 PM
(This post was last modified: Feb-05-2021, 03:56 PM by muzikman.
Edit Reason: Sorry, screwed up a few things.
)
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.
Posts: 1,583
Threads: 3
Joined: Mar 2020
Feb-05-2021, 04:56 PM
(This post was last modified: Feb-05-2021, 04:57 PM by bowlofred.)
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).
Posts: 6,792
Threads: 20
Joined: Feb 2020
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
Posts: 138
Threads: 26
Joined: Nov 2020
(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
|