Not understanding how the bitwise unary inversion ' ~ ' operator works [duplicate] - c++

This question already has answers here:
bit-wise operation unary ~ (invert)
(5 answers)
Closed 7 years ago.
int x=10;
cout<<~x;
this code prints -11. if it was simple inversion then for 00001010 the bits should be 11110101, which on conversion to decimal is -117. I have tried searching but no luck pls tell what is happening here?
I am using mingw compiler, if its of any help.

That is working as expected. "11110101" is -11 in two's complement.
As a side note, "int" is either 16 or 32 bits, so you're actually talking about
"00000000 00001010" or "00000000 00000000 00000000 00001010" respectively.

~x is equal to −x − 1. Therefore, ~10 = -10 - 1 = -11.
Using 1-byte , 10 is represented as 0000 1010. Its bit-wise NOT is 1111 0101. Generally computer represents signed integers in 2's complement format. So, decimal equivalent of 1111 0101 is -11, How?
An N-bit number w represented in 2's complement as aN-1aN-2....a0 can be converted to decimal as
Therefore,
1111 01012 = -1*27 1*26 + 1*25 + 1*24 + 0*23 + 1*22 + 0*21 + 1*20 = -128 + 117 = -11

The ~ operator works as you think it does. It's just negative numbers don't work how you think they do. Negative numbers are encoded as a two's complement http://en.wikipedia.org/wiki/Two%27s_complement
Basically, the value of the highest bit is subtracted from the value of the lower bits.

Related

Wrong output in c++ , i=65530 and when we print value of i it gives -6 instate of 65530. why?

I was creating a simple variable printing program and there is unexpected output.
The program gives output -6, but I would have expected 65530.
Why?
#include<iostream>
int main(){
short int i=65530;
std::cout<<i;
}
This has to do with the binary represenation of the type you have used.
As a 16 bit binary: 65530 === 1111 1111 1111 1010
But you have used short int which is a signed number and in it's binary definition it is represented by 1 bit as a sign and 15 bits as the number:
(1)111 1111 1111 1010
So why are there so many 1's in the representation?
Why don't the 15 bits look like a 6 in binary ( (1)000 0000 0000 0110)?
It's because of the way that negative numbers are represented in binary.
To represent signed numbers in binary, a format is used which is called Two's complement.
So here is an example of this transformation of the number -6
Take the number and transform it to binary. (6 in binary === 0000 0000 0000 0110
Exchange 1's to 0's and 0's to 1's (1111 1111 1111 1001)
To get the result - Add 1 to the previous transformation: (1111 1111 1111 1010)
As You can see exactly the same binary representation is for (unsigned)65530 as is for (signed)-6.
It's all in the interpretation of the bits.
That's why You have to be carefull nearing the maximum values of a representation in a type.
In this case to store this value You could:
Change the type to unsigned short int
Change to larger type.
You declared i as a short int, which is a 16-bit signed type. This means that the highest number it can represent is actually 32767 (2^15-1) and the smallest is -32768 (-2^15). 65530 overflows that limit. So if you had printed 32768, it would instead overflow to -32768, 32769 would overflow to -32767 and so on. See more topics on binary representations of signed numbers to understand this process better

Web compiler outputting weird results [duplicate]

This question already has answers here:
What is “two's complement”?
(24 answers)
Closed 5 years ago.
Take a look at this compiler:
https://ideone.com/Y09Z0N
The code is very simple:
cout << ~5;
And this outputs -6
Now I'm no C++ guru, but somehow I remember that the ~ operator should flip a numbers bits, and since 5 is 101, I would expect to get 010, which is 2, or more precisely 5 is 0000......101 and I should get 1111...010 which should be a really big negative number and not 6 (110). The question is: am I wrong about the operator or am I missing something?
Negative integers are typically represented in two's complement.
This allows basic operations such as addition and subtraction to work with negative numbers in the exactly the same way as positive ones. In that form, negatives are represented as:
00000000 = 0
11111111 = -1
11111110 = -2
11111101 = -3
11111100 = -4
11111011 = -5
11111010 = -6
So indeed -6 = ~5
This is actually a subtle thing about two's complement.
I will write your numbers in base 16, at the size of the variable (I assume 32 bits, but you can alter the answer for other sizes).
5 is 0x00000005. ~5 is its negation, 0xFFFFFFFA. Add 5 to that, and you see ~5 + 5 is 0xFFFFFFFF. Add one more and you get 0x00000000, or 0, due to overflow.
Two's complement representation has made it so that incrementing past 0x7FFFFFFF (or 2147483647) is the actual overflow (and 0x80000000 is -2147483648), and simply the increment from -1 to 0 has been made not to cause an overflow.
You may read more about two's complement representation and also ask for more info from me if you wish.

fixed point subtraction for two's complement data

I have some real data. For example +2 and -3. These data are represented in two's complement fixed point with 4 bit binary value where MSB represents the sign bit and number of fractional bit is zero.
So +2 = 0010
-3 = 1101
addition of this two numbers is (+2) + (-3)=-1
(0010)+(1101)=(1111)
But in case of subtraction (+2)-(-3) what should i do?
Is it needed to take the two's complement of 1101 (-3) again and add with 0010?
You can evaluate -(-3) in binary and than simply sums it with the other values.
With two's complement, evaluate the opposite of a number is pretty simple: just apply the NOT binary operation to every digits except for the less significant bit. The equation below uses the tilde to rapresent the NOT operation of a single bit and assumed to deal with integer rapresented by n bits (n = 4 in your example):
In your example (with an informal notation): -(-3) = -(1101) = 0011

Why 10^1 is 11?

I am currently learning C++. I was trying to compute power of an integer using the expression:
val=10^1;
Instead of expected answer 10, the result was 11. I have fixed the problem by using pow function of math.h library but I am wondering why this statement is giving me the wrong result.
No! Do you think that is the power? Don't forgot this (In C++ and some of the programming languages):
Be sure to read this:
Operators (cplusplus)
Bitwise operation (wikipedia)
A bitwise XOR takes two bit patterns of equal length and performs the logical exclusive OR operation on each pair of corresponding bits. The result in each position is 1 if only the first bit is 1 or only the second bit is 1, but will be 0 if both are 0 or both are 1. In this we perform the comparison of two bits, being 1 if the two bits are different, and 0 if they are the same. For example:
0101 (decimal 5)
XOR 0011 (decimal 3)
= 0110 (decimal 6)
The bitwise XOR may be used to invert selected bits in a register (also called toggle or flip). Any bit may be toggled by XORing it with 1. For example, given the bit pattern 0010 (decimal 2) the second and fourth bits may be toggled by a bitwise XOR with a bit pattern containing 1 in the second and fourth positions:
0010 (decimal 2)
XOR 1010 (decimal 10)
= 1000 (decimal 8)
This technique may be used to manipulate bit patterns representing sets of Boolean states.
Source: Wikipedia
That's the bitwise exclusive-or operator, not power. In binary:
10 = 1010
1 = 0001
val= 1011 = 11 in decimal
In C and C++, 10^1 is 10 XOR 1, not 10 to the power of 1.
^ is the binary XOR operator in C++:
10 ^ 1 =
00001010
^ 00000001
= --------
00001011 = 11
Because ^ is the exclusive or operator and not the exponentiation operator. Basically, because the last bit of 10 in binary is 0, by applying exclusive or of 1 the last bit gets converted to 1 because it is different than 0.
Because in C++ there is no power operator: ^ is a XOR.
1010 is 10102 in binary; 110 is 00012. XORing them together gives 10112, which is 1110.
If you would like to obtain 10n, use the pow function from <cmath> header:
val=pow(10, 1);

Why does a right shift on a signed integer causes an overflow?

Given any 8 bits negative integer (signed so between -1 and -128), a right shift in HLA causes an overflow and I don't understand why. If shifted once, it should basically divide the value by 2. This is true for positive numbers but obviously not for negative. Why? So for example if -10 is entered the result is +123.
Program cpy;
#include ("stdlib.hhf")
#include ("hla.hhf")
static
i:int8;
begin cpy;
stdout.put("Enter value to divide by 2: ");
stdin.geti8();
mov(al,i);
shr(1,i); //shift bits one position right
if(#o)then // if overlow
stdout.put("overflow");
endif;
end cpy;
Signed numbers are represented with their 2's complement in binary, plus a sign bit "on the left".
The 2's complement of 10 coded on 7 bits is 1110110, and the sign bit value for negative numbers is 1.
-10: 1111 0110
^
|
sign bit
Then you shift it to the right (when you right shift zeroes get added to the left):
-10 >> 1: 0111 1001
^
|
sign bit
Your sign bit is worth 0 (positive), and 1111011 is 123 in decimal.