Why is ~3 equal to -4 in Python? - twos-complement

I'm getting started in Python programming. I'm reading a basic tutorial, but this point is not very clear to me. I would appreciate any help you can give me.

~3 means 'invert' 3. With two's complement on natural number datatypes, this becomes -4, as the binary representation is inverted (all bits are flipped).

~3 means "change all the 1s to 0s and 0s to 1s", so if 3 in binary is 0000000000000011, then ~3 is 1111111111111100. since the first bit of ~3 is a 1, its a negative number. to find out which negative number, in 2s comliment, you invert all bits and add 1, so inverted we are back to 3, then added 1 we get 4.

Because signed integers are usually stored using two's complement, which means that the bitwise inverse of an integer is equal to its algebraic inverse minus one.

It's the invert operator, and returns the bitwise inverse of the number you give it.

It's not just Python, it's the integer numeric representation of almost all modern computers: two's complement. By the definition of two's complement, you get a negative number by complementing the positive number and adding one. In your example, you complemented with ~ but did not add one, so you got the negative of your number minus one.

Related

Can the bitwise AND of some positive integers be negative?

Can the bitwise AND of some positive integers be negative?
Let's say I have some numbers 1,2,3..N. For example, take N=7 and I want to find a subarray which results me in a negative result after bitwise AND operation.
Taking 4,5,6,7 gives me 4(100) but what subarray(for any N) could give me negative result?
(In most/commonly used encodings) sign is stored in first bit.
For first bit to be 1 (meaning negative number) after AND, both bits need to be 1 before that. So it means only 2 negative numbers can make a negative number with AND.
This is true both for integers and floats (IEEE754) (the most common int and float implementations) but basically anything that can store negative numbers has to store the sign somewhere... and as positive numbers are the "default", it's minus that gets marked as 1.
Can the bitwise AND of some positive integers be negative?
No, it can't.
A negative number has the top bit set. All positive numbers have the top bit unset. A zero bit AND a zero bit results in a zero bit. This applies to any number of bitwise AND operations performed on any number of positive integers.
And it also applies if you include zero.
In fact, if you perform an bitwise AND on a collection of integers, the result will only be negative if all of the integers are less than zero.
Note that above is for twos' complement binary representations. All modern mainstream computer instruction sets use twos' complement to represent integers.
With ones' complement you actually have two zeros +0 and -0. But if you treat -0 as negative then the same logic applies.
Bitwise AND'ing of floating point number representations ... and treating the results as numbers ... doesn't make a lot of sense. So I haven't considered that.

Adding fixed point integers in two's Compments

I was referring a past paper for a exam then I found this. I am confused about this question. Help would be great.
Add the following numbers as fixed point integers.Your calculations must be shown by using binary numbers in two's complement
-9.25+(-2.5)
The phrase fixed point integers (where a number is generally either fixed-point or an integer) leads me to believe it's really just a scaled integer.
In other words, the actual representation of those numbers would be -925 and -250 (with a scale of 100).
So I would think the process would be to convert those to binary, do the two's complement addition, then convert back to decimal, hopefully giving -1175 would would scale to -11.75).

NOT(~) bitwise operator on signed type number

I'm having little trouble understanding how not(~) operator work for positive signed number.
as an example -ve numbers are stored in 2's compliment
int a=-5;
cout<<bitset<32>(a)<<endl; // 11111111111111111111111111111011
cout<<bitset<32>(~a)<<endl; // 00000000000000000000000000000100
cout<<(~a)<<endl; // 4
4 is an expected output
but
int a=5;
cout<<bitset<32>(a)<<endl; // 00000000000000000000000000000101
cout<<bitset<32>(~a)<<endl; // 11111111111111111111111111111010
cout<<(~a)<<endl; // -6
how come -6?
The bitwise not (~) operator can basically be summarized as the following
~x == -(x+1)
The reason for this is because negation (unary -) uses 2's complement, in general.
Two's complement is defined as taking the bitwise not and then adding one i.e. -x == (~x) + 1. Simple transposition of the + 1 to the other side and then using distributive property of the negative sign (i.e. distributive property of multiplication, specifically with -1 in this case), we get the equation on top.
In a more mathematical sense:
-x == (~x) + 1 // Due to way negative numbers are stored in memory (in 2's complement)
-x - 1 == ~x // Transposing the 1 to the other side
-(x+1) == ~x // Distributing the negative sign
The C++ standard only says that the binary NOT operator (~) flips all the bits that are used to represent the value. What this means for the integer value depends on what interpretation of the bits your machine uses. The C++ standard allows the following three representations of signed integers:
sign+magnitde: There is a sign bit followed by bits encoding the magnitude.
one's complement: The idea is to represent -x by flipping all bits of x. This is similar to sign+magnitude where in the negative cases the magnitude bits are all flipped. So, 1...1111 would be -0, 1...1110 would be -1, 1...1101 would be -2 and so on...
two's complement: This representation removes one of two possible encodings for zero and adds a new value at the lower end. In two's complement 1...1111 represents -1, 1...1110 represents -2 and so on. So, it's basically one shifted down compared to one's complement.
Two's complement is much more popular these days. X86, X64, ARM, MIPS all use this representation for signed numbers as far as I know. Your machine apparently also uses two's complement because you observed ~5 to be -6.
If you want to stay 100% portable you should not rely on the two's complement representation and only use these kinds of operators on unsigned types.
It is due to how the computer understands signed numbers.
take a byte : 8 bits.
1 (the strong one) for de sign
7 for the number
as a whole :
so from -128 to +127
for negative numbers :
-128 to -1
for positive numbers : 0 to 127.
there is no need to have two 0 in numbers, therefore, there is one more negative number.

Definition of Two's Complement?

I've been reading over a couple of questions/answers here:
twos-complement-in-python
is-twos-complement-notation-of-a-positive-number-the-same-number
Someone gave some sample code to create a two's complement of a number:
def twos_comp(val, bits):
"""compute the 2's compliment of int value val"""
if( (val&(1<<(bits-1))) != 0 ):
val = val - (1<<bits)
return val
In addition someone defined two's complement as thus:
Two's complement notation uses the n-bit two's complement to flip the
sign. For 8-bit numbers, the number is subtracted from 2^8 to produce
its negative.
These declarations went unchallenged. However, that chides with my understand of a two's complement is. I thought it's calculated by inverting the binary number and adding 1. (With the understanding that the number representation has a limited number of bits.)
Additionally, the two's complement is supposed to have the property that it is the additive inverse of the original number. But, the output from twos_comp doesn't appear to have that. In my hand calculations (and some test code I wrote) with my definition , I see that when a number and the twos complement of it are added together, a 1 is overflowed and the rest of the bits are zero, thus it has the additive inverse property.
Are there multiple definitions for twos complement, am I confused, or is that definition and function from the other posts just plain wrong?
Twos complement is in fact calculated by inverting the binary number and adding 1, for negative numbers. Such that abs(-1)=1=01 -> bitwise_inv(abs(-1))+abs(-1)=FE+1=FF. This is equivalent to the definition provided of subtracting the number from 2^8 (this should not be hard to see).
The sample code you provided, does not calculate twos complement in any useful way. I don't at all understand whats its trying to do, appears to quite be quite different from "subtracting the number from 2^8" as subtracts 2*8 from the number, while also failing to remember that when we refer to the value of a twos complement number what we mean is its unsigned value.
Here is a more correct implementation, using the same template. Notice that this precisely does "subtract the number from 2^8."
def twos_c(val,bits):
if ((val&(1<<(bits-1)))!=0):
val=(1<<bits)-abs(val)
return val

How to divide two negative numbers using the two's complement method?

I was studying more about binary arithmetics and came across the problem -21/-3. The expected answer is 7. Of course I know we can do it by canceling the negative sign and dividing 21 by 3. I have seen the beauty of two's complement in the subtraction of two numbers.
So i started out like this:
-21 is: 11101011
-3 is: 11111101
Initially I tried out dividing but as numerator is greater than denominator division is not possible. Also it is clear that it is the equivalent of dividing 235 by 253. So my question is how can I divide two negative numbers using two's complement method. Is this division allowed or isn't it possible to divide like this?