Tutorial :Bits representation of negative numbers



Question:

This is a doubt regarding the representation of bits of signed integers. For example, when you want to represent -1, it is equivalent to 2's complement of (+1). So -1 is represented as 0xFFFFFFF. Now when I shift my number by 31 and print the result it is coming back as -1.

signed int a = -1;  printf(("The number is %d ",(a>>31));//this prints as -1  

So can anyone please explain to me how the bits are represented for negative numbers?

Thanks.


Solution:1

When the top bit is zero, the number is positive. When it's 1, the number is negative.

Negative numbers shifted right keep shifting a "1" in as the topmost bit to keep the number negative. That's why you're getting that answer.

For more about two's complement, see this Stackoverflow question.


@Stobor points out that some C implementations could shift 0 into the high bit instead of 1. [Verified in Wikipedia.] In Java it's dependably an arithmetic shift.

But the output given by the questioner shows that his compiler is doing an arithmetic shift.


Solution:2

The C standard leaves it undefined whether the right shift of a negative (necessarily signed) integer shifts zeroes (logical shift right) or sign bits (arithmetic shift right) into the most significant bit. It is up to the implementation to choose.

Consequently, portable code ensures that it does not perform right shifts on negative numbers. Either it converts the value to the corresponding unsigned value before shifting (which is guaranteed to use a logical shift right, putting zeroes into the vacated bits), or it ensures that the value is positive, or it tolerates the variation in the output.


Solution:3

This is an arithmetic shift operation which preserves the sign bit and shifts the mantissa part of a signed number.

cheers


Solution:4

Basically there are two types of right shift. An unsigned right shift and a signed right shift. An unsigned right shift will shift the bits to the right, causing the least significant bit to be lost, and the most significant bit to be replaced with a 0. With a signed right shift, the bits are shifted to the right, causing the least significant bit be be lost, and the most significant bit to be preserved. A signed right shift divides the number by a power of two (corresponding to the number of places shifted), whereas an unsigned shift is a logical shifting operation.

The ">>" operator performs an unsigned right shift when the data type on which it operates is unsigned, and it performs a signed right shift when the data type on which it operates is signed. So, what you need to do is cast the object to an unsigned integer type before performing the bit manipulation to get the desired result.


Solution:5

Have a look at two's complement description. It should help.


Solution:6

EDIT: When the below was written, the code in the question was written as:

unsigned int a = -1;  printf(("The number is %d ",(a>>31));//this prints as -1  

If unsigned int is at least 32 bits wide, then your compiler isn't really allowed to produce -1 as the output of that (with the small caveat that you should be casting the unsigned value to int before you pass it to printf).

Because a is an unsigned int, assigning -1 to it must give it the value of UINT_MAX (as the smallest non-negative value congruent to -1 modulo UINT_MAX+1). As long as unsigned int has at least 32 bits on your platform, the result of shifting that unsigned quantity right by 31 will be UINT_MAX divided by 2^31, which has to fit within int. (If unsigned int is 31 bits or shorter, it can produce whatever it likes because the result of the shift is unspecified).


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »