Why is it that ~2 is equal to -3? How does ~
operator work?
17 Answers
Remember that negative numbers are stored as the two's complement of the positive counterpart. As an example, here's the representation of -2 in two's complement: (8 bits)
1111 1110
The way you get this is by taking the binary representation of a number, taking its complement (inverting all the bits) and adding one. Two starts as 0000 0010, and by inverting the bits we get 1111 1101. Adding one gets us the result above. The first bit is the sign bit, implying a negative.
So let's take a look at how we get ~2 = -3:
Here's two again:
0000 0010
Simply flip all the bits and we get:
1111 1101
Well, what's -3 look like in two's complement? Start with positive 3: 0000 0011, flip all the bits to 1111 1100, and add one to become negative value (-3), 1111 1101.
So if you simply invert the bits in 2, you get the two's complement representation of -3.
The complement operator (~) JUST FLIPS BITS. It is up to the machine to interpret these bits.
~
flips the bits in the value.
Why ~2
is -3
has to do with how numbers are represented bitwise. Numbers are represented as two's complement.
So, 2 is the binary value
00000010
And ~2 flips the bits so the value is now:
11111101
Which, is the binary representation of -3.
As others mentioned ~
just flipped bits (changes one to zero and zero to one) and since two's complement is used you get the result you saw.
One thing to add is why two's complement is used, this is so that the operations on negative numbers will be the same as on positive numbers. Think of -3
as the number to which 3
should be added in order to get zero and you'll see that this number is 1101
, remember that binary addition is just like elementary school (decimal) addition only you carry one when you get to two rather than 10.
1101 +
0011 // 3
=
10000
=
0000 // lose carry bit because integers have a constant number of bits.
Therefore 1101
is -3
, flip the bits you get 0010
which is two.
I know the answer for this question is posted a long back, but I wanted to share my answer for the same.
For finding the one’s complement of a number, first find its binary equivalent. Here, decimal number 2
is represented as 0000 0010
in binary form. Now taking its one’s complement by inverting (flipping all 1’s into 0’s and all 0’s into 1’s) all the digits of its binary representation, which will result in:
0000 0010 → 1111 1101
This is the one’s complement of the decimal number 2. And since the first bit, i.e., the sign bit is 1 in the binary number, it means that the sign is negative for the number it stored. (here, the number referred to is not 2 but the one’s complement of 2).
Now, since the numbers are stored as 2’s complement (taking the one’s complement of a number plus one), so to display this binary number, 1111 1101
, into decimal, first we need to find its 2’s complement, which will be:
1111 1101 → 0000 0010 + 1 → 0000 0011
This is the 2’s complement. The decimal representation of the binary number, 0000 0011
, is 3
. And, since the sign bit was one as mentioned above, so the resulting answer is -3
.
Hint: If you read this procedure carefully, then you would have observed that the result for the one’s complement operator is actually, the number (operand - on which this operator is applied) plus one with a negative sign. You can try this with other numbers too.
int a=4; System.out.println(~a); Result would be :-5
'~' of any integer in java represents 1's complement of the no. for example i am taking ~4,which means in binary representation 0100. first , length of an integer is four bytes,i.e 4*8(8 bits for 1 byte)=32. So in system memory 4 is represented as 0000 0000 0000 0000 0000 0000 0000 0100 now ~ operator will perform 1's complement on the above binary no
i.e 1111 1111 1111 1111 1111 1111 1111 1011->1's complement the most significant bit represents sign of the no(either - or +) if it is 1 then sign is '-' if it is 0 then sign is '+' as per this our result is a negative number, in java the negative numbers are stored in 2's complement form, the acquired result we have to convert into 2's complement( first perform 1's complement and just add 1 to 1's complement). all the one will become zeros,except most significant bit 1(which is our sign representation of the number,that means for remaining 31 bits 1111 1111 1111 1111 1111 1111 1111 1011 (acquired result of ~ operator) 1000 0000 0000 0000 0000 0000 0000 0100 (1's complement)
1 (2's complement)
1000 0000 0000 0000 0000 0000 0000 0101 now the result is -5 check out this link for the video <[Bit wise operators in java] https://youtu.be/w4pJ4cGWe9Y
Simply ...........
As 2's complement of any number we can calculate by inverting all 1s to 0's and vice-versa than we add 1 to it..
Here N= ~N produce results -(N+1) always. Because system store data in form of 2's complement which means it stores ~N like this.
~N = -(~(~N)+1) =-(N+1).
For example::
N = 10 = 1010
Than ~N = 0101
so ~(~N) = 1010
so ~(~N) +1 = 1011
Now point is from where Minus comes. My opinion is suppose we have 32 bit register which means 2^31 -1 bit involved in operation and to rest one bit which change in earlier computation(complement) stored as sign bit which is 1 usually. And we get result as ~10 = -11.
~(-11) =10 ;
The above is true if printf("%d",~0); we get result: -1;
But printf("%u",~0) than result: 4294967295 on 32 bit machine.
The Bitwise complement operator(~) is a unary operator.
It works as per the following methods
First it converts the given decimal number to its corresponding binary value.That is in case of 2 it first convert 2 to 0000 0010 (to 8 bit binary number).
Then it converts all the 1 in the number to 0,and all the zeros to 1;then the number will become 1111 1101.
that is the 2's complement representation of -3.
In order to find the unsigned value using complement,i.e. simply to convert 1111 1101 to decimal (=4294967293) we can simply use the %u during printing.
Simply speaking, ~
is to find the symmetric value (to -0.5).
~a
and a
should be symmetric to the mirror in the middle of 0 and -1.
-5,-4,-3,-2,-1 | 0, 1, 2, 3, 4
~0 == -1
~1 == -2
~2 == -3
~3 == -4
The reason for this is due to how computers represent negative values.
Say, if positive value uses 1
to count, negative value uses 0
.
1111 1111 == -1
1111 1110 == -2; // add one more '0' to '1111 1111'
1111 1101 == -3; // add one more '0' to '1111 1110'
Finally, ~i == -(i+1)
.
I think for most people the confusion part comes from the difference between decimal number and signed binary number, so lets clarify it first:
for human decimal world: 01 means 1, -01 means -1, for computer's binary world: 101 means 5 if it is unsigned. 101 means (-4 + 1) if is signed while the signed digit is at position x. | x
so 2's flipped bit = ~2 = ~(010) = 101 = -4 + 1 = -3 the confusion comes from mixing up the signed result(101=-3) and the unsinged result(101=5)
tl;dr ~
flips the bits. As a result the sign changes. ~2
is a negative number (0b..101
). To output a negative number ruby
prints -
, then two's complement of ~2
: -(~~2 + 1) == -(2 + 1) == 3
. Positive numbers are output as is.
There's an internal value, and its string representation. For positive integers, they basically coincide:
irb(main):001:0> '%i' % 2
=> "2"
irb(main):002:0> 2
=> 2
The latter being equivalent to:
irb(main):003:0> 2.to_s
"2"
~
flips the bits of the internal value. 2
is 0b010
. ~2
is 0b..101
. Two dots (..
) represent an infinite number of 1
's. Since the most significant bit (MSB) of the result is 1
, the result is a negative number ((~2).negative? == true
). To output a negative number ruby
prints -
, then two's complement of the internal value. Two's complement is calculated by flipping the bits, then adding 1
. Two's complement of 0b..101
is 3
. As such:
irb(main):005:0> '%b' % 2
=> "10"
irb(main):006:0> '%b' % ~2
=> "..101"
irb(main):007:0> ~2
=> -3
To sum it up, it flips the bits, which changes the sign. To output a negative number it prints -
, then ~~2 + 1
(~~2 == 2
).
The reason why ruby
outputs negative numbers like so, is because it treats the stored value as a two's complement of the absolute value. In other words, what's stored is 0b..101
. It's a negative number, and as such it's a two's complement of some value x
. To find x
, it does two's complement of 0b..101
. Which is two's complement of two's complement of x
. Which is x
(e.g ~(~2 + 1) + 1 == 2
).
In case you apply ~
to a negative number, it just flips the bits (which nevertheless changes the sign):
irb(main):008:0> '%b' % -3
=> "..101"
irb(main):009:0> '%b' % ~-3
=> "10"
irb(main):010:0> ~-3
=> 2
What is more confusing is that ~0xffffff00 != 0xff
(or any other value with MSB equal to 1
). Let's simplify it a bit: ~0xf0 != 0x0f
. That's because it treats 0xf0
as a positive number. Which actually makes sense. So, ~0xf0 == 0x..f0f
. The result is a negative number. Two's complement of 0x..f0f
is 0xf1
. So:
irb(main):011:0> '%x' % ~0xf0
=> "..f0f"
irb(main):012:0> (~0xf0).to_s(16)
=> "-f1"
In case you're not going to apply bitwise operators to the result, you can consider ~
as a -x - 1
operator:
irb(main):018:0> -2 - 1
=> -3
irb(main):019:0> --3 - 1
=> 2
But that is arguably of not much use.
An example Let's say you're given a 8-bit (for simplicity) netmask, and you want to calculate the number of 0
's. You can calculate them by flipping the bits and calling bit_length
(0x0f.bit_length == 4
). But ~0xf0 == 0x..f0f
, so we've got to cut off the unneeded bits:
irb(main):014:0> '%x' % (~0xf0 & 0xff)
=> "f"
irb(main):015:0> (~0xf0 & 0xff).bit_length
=> 4
Or you can use the XOR operator (^
):
irb(main):016:0> i = 0xf0
irb(main):017:0> '%x' % i ^ ((1 << i.bit_length) - 1)
=> "f"
First we have to split the given digit into its binary digits and then reverse it by adding at the last binary digit.After this execution we have to give opposite sign to the previous digit that which we are finding the complent ~2=-3 Explanation: 2s binary form is 00000010 changes to 11111101 this is ones complement ,then complented 00000010+1=00000011 which is the binary form of three and with -sign I.e,-3
The bit-wise operator is a unary operator which works on sign and magnitude method as per my experience and knowledge.
For example ~2 would result in -3.
This is because the bit-wise operator would first represent the number in sign and magnitude which is 0000 0010 (8 bit operator) where the MSB is the sign bit.
Then later it would take the negative number of 2 which is -2.
-2 is represented as 1000 0010 (8 bit operator) in sign and magnitude.
Later it adds a 1 to the LSB (1000 0010 + 1) which gives you 1000 0011.
Which is -3.
Javascript tilde (~) coerces a given value to the one's complement--all bits are inverted. That's all tilde does. It's not sign opinionated. It neither adds nor subtracts any quantity.
0 -> 1
1 -> 0
...in every bit position [0...integer nbr of bits - 1]
On standard desktop processors using high-level languages like JavaScript, BASE10 signed arithmetic is the most common, but keep in mind, it's not the only kind. Bits at the CPU level are subject to interpretation based on a number of factors. At the 'code' level, in this case JavaScript, they are interpreted as a 32-bit signed integer by definition (let's leave floats out of this). Think of it as quantum, those 32-bits represent many possible values all at once. It depends entirely on the converting lens you view them through.
JavaScript Tilde operation (1's complement)
BASE2 lens
~0001 -> 1110 - end result of ~ bitwise operation
BASE10 Signed lens (typical JS implementation)
~1 -> -2
BASE10 Unsigned lens
~1 -> 14
All of the above are true at the same time.
It's easy:
Before starting please remember that
1 Positive numbers are represented directly into the memory.
2. Whereas, negative numbers are stored in the form of 2's compliment.
3. If MSB(Most Significant bit) is 1 then the number is negative otherwise number is
positive.
You are finding ~2:
Step:1 Represent 2 in a binary format
We will get, 0000 0010
Step:2 Now we have to find ~2(means 1's compliment of 2)
1's compliment
0000 0010 =================> 1111 1101
So, ~2 === 1111 1101, Here MSB(Most significant Bit) is 1(means negative value). So,
In memory it will be represented as 2's compliment(To find 2's compliment first we
have to find 1's compliment and then add 1 to it.)
Step3: Finding 2's compliment of ~2 i.e 1111 1101
1's compliment Adding 1 to it
1111 1101 =====================> 0000 0010 =================> 0000 0010
+ 1
---------
0000 0011
So, 2's compliment of 1111 1101, is 0000 0011
Step4: Converting back to decimal format.
binary format
0000 0011 ==============> 3
In step2: we have seen that the number is negative number so the final answer would
be -3
So, ~2 === -3