tags:

views:

159

answers:

4

Consider these definitions:

int x=5;
int y=-5;
unsigned int z=5;

How are they stored in memory? Can anybody explain the bit representation of these in memory?

Can int x=5 and int y=-5 have same bit representation in memory?

+1  A: 

Here is the very nice link which explains the storage of signed and unsigned INT in C -

http://answers.yahoo.com/question/index?qid=20090516032239AAzcX1O

Taken from this above article -

"process called two's complement is used to transform positive numbers into negative numbers. The side effect of this is that the most significant bit is used to tell the computer if the number is positive or negative. If the most significant bit is a 1, then the number is negative. If it's 0, the number is positive."

Sachin Shanbhag
ok on 16 bit compiler can you tell me how int x=5 and int y=-5 internally store in memory. Please provide bit representation
Anand Kumar
Note that 2's complement is not the only signed representation allowed for a C implementation - both ones complement and sign-magnitude are also allowed.
caf
A: 

Assuming int is a 16 bit integer (which depends on the C implementation, most are 32 bit nowadays) the bit representation differs like the following:

 5 = 0000000000000101
-5 = 1111111111111011

if binary 1111111111111011 would be set to an unsigned int, it would be decimal 65531.

elsni
ISO C does _not_ mandate 2's complement representation, by the way.
paxdiablo
ok on 16 bit compiler can you tell me how int x=5 and int y=-5 internally store in memory. Please provide bit representation
Anand Kumar
@Anand: what do you really want? there is the bit representation (in two's complement) in the answer already.
Jens Gustedt
Hi i am asking if i write signed int x=5; then it will store value in 2's complement form or not and if i write signed int x= -5; then it will store value in 2's complement or not.
Anand Kumar
+1  A: 

The C standard specifies that unsigned numbers will be stored in binary. (With optional padding bits). Signed numbers can be stored in one of three formats: Magnitude and sign; two's complement or one's complement. Interestingly that rules out certain other representations like Excess-n or Base −2.

However on most machines and compilers store signed numbers in 2's complement.

int is normally 16 or 32 bits. The standard says that int should be whatever is most efficient for the underlying processor, as long as it is >= short and <= long then it is allowed by the standard.

On some machines and OSs history has causes int not to be the best size for the current iteration of hardware however.

Douglas Leeder
ok on 16 bit compiler can you tell me how int x=5 and int y=-5 internally store in memory. Please provide bit representation
Anand Kumar
-1: Unfortunately your answer is wrong. C prescribes very precisely how integers are to be represented. In particular for unsigned types there is not much choice for a compiler implementation. But even for signed types the standard is quite restrictive. And `int` is by no ways the type that is most efficient for the processor. In most cases it is nowadays stuck with 32 bits (merely for syntactical reasons than anything else), where the most efficient often is 64.
Jens Gustedt
@Jens Gustedt: "Unfortunately", Douglas' answer is very much correct. The standard does not discriminate between two's complement, one's complement or signed magnitude, it only states that the positive representations of signed ints must be identical to the representation of the same values in unsigned ints. The standard also states that "a 'plain' **int** object has the natural size suggested by the architecture of the execution environment". That implementations screwed this up is not the fault of the language. Douglas is absolutely correct, so I give +1 to offset your -1.
DevSolar
@DevSolar: The standard has the phrase that you are citing, yes, but on the other hand it restricts much of you could implement it, so the result is as I stated, I think. (There are only 5 standard integer types, and if you want to have 8, 16, 32, 64 and 128 bit types, you have no choice than to have `int` at 32 bit.) And I think that Douglas' phrase `the C standard doesn't specify how integers are stored in memory` can't stand like this. The standard has several pages to specify this. E.g it states, that there are only the three representations of sign that you mention, and no others.
Jens Gustedt
Ok, I've actually found a copy of the standard, so I'll correct my answer.
Douglas Leeder
@Jens Gustedt: But it does not tell which one of the three types it has to be, or whether there are padding bits or not. It also *does* state that **int** should be the "natural" size for the architecture. And you are in no way limited to the "standard" integer types, as `<stdint.h>` offers a compliant way to define additional integer types (like, 24 or 36 bits).
DevSolar
@Jens Gustedt: I've edited my answer now I've found a reference for the C spec, is that better?
Douglas Leeder
I guess you can't use standard C on a machine with Ternary memory?
Douglas Leeder
@Douglas: great, objection removed.
Jens Gustedt
I suppose that bit operators wouldn't make much sense without binary integers.
Douglas Leeder
+8  A: 

ISO C (C99) states the difference. The int data type is signed and has a minimum range of at least -32767 through 32767 inclusive. The actual values are given in limits.h as INT_MIN and INT_MAX respectively.

An unsigned int has a minimal range of 0 through 65535 inclusive with the actual maximum value being UINT_MAX from that same header file.

Beyond that, the standard does not mandate twos complement notation for encoding the values, that's just one of the possibilities. The three allowed types would have encodings of the following for 5 and -5 (using 16-bit data types):

    twos complement     | ones complement     | sign/magnitude
 5  0000 0000 0000 0101 | 0000 0000 0000 0101 | 0000 0000 0000 0101
-5  1111 1111 1111 1011 | 1111 1111 1111 1010 | 1000 0000 0000 0101
  • In twos complement, you get a negative of a number by inverting all bits then adding 1.
  • In ones complement, you get a negative of a number by inverting all bits.
  • In sign/magnitude, the top bit is the sign so you just invert that to get the negative.

Note that positive values have the same encoding for all representations, only the negative values are different.

Note further that, for unsigned values, you do not need to use one of the bits for a sign. That means you get more range on the positive side (at the cost of no negative encodings, of course).

And no, 5 and -5 cannot have the same encoding regardless of which representation you use. Otherwise, there'd be no way to tell the difference.

paxdiablo
It does mandate a choice of 2's complement, ones complement or sign-magnitude, though.
caf
Could a conforming implementation use the same representation for signed and unsigned numbers, and merely force the sign bit to be '0' for operations on types declared 'unsigned' (such that it would essentially be a 'padding bit')?
supercat
Possibly, I think that may be allowed but, since the minimal range is 0-65536, you'd need at least 17 bits for that scheme. That would count out 16-bit unsigned integers but probably be okay with 32-bit integers. I'm not sure of this since I haven't looked closely into whether wrapping of unsigned is specc'ed by ISO but it seems inefficient/wasteful for the current crop of CPUs at least.
paxdiablo