42

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?

SQB
  • 3,926
  • 2
  • 28
  • 49
Anand Kumar
  • 499
  • 1
  • 4
  • 7

5 Answers5

51

ISO C states what the differences are.

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):

        two's 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 two's 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.


As an aside, there are currently moves underway, in both C and C++ standards, to nominate two's complement as the only encoding for negative integers.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 5
    It does mandate a choice of 2's complement, ones complement or sign-magnitude, though. – caf Sep 28 '10 at 11:25
  • 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 Sep 28 '10 at 22:56
  • 1
    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 Sep 29 '10 at 00:01
  • Two's complement is a very elegant system. Not only is it easy to implement in hardware, it allows you to use the existing addition hardware to perform subtraction - adding a two's complement number to an unsigned integer performs a subtraction. – Spatial Aug 19 '13 at 16:50
  • Hello. I have before this only known of the sign/magnitude encoding, and it's assumed in article about Java https://www.javamex.com/java_equivalents/unsigned.shtml "it preserves the sign" ... so is this three-variant-freedom available/used in other languages than C? – Valter Ekholm Jul 16 '19 at 22:35
5

Because it's all just about memory, in the end all the numerical values are stored in binary.

A 32 bit unsigned integer can contain values from all binary 0s to all binary 1s.

When it comes to 32 bit signed integer, it means one of its bits (most significant) is a flag, which marks the value to be positive or negative.

Prashant
  • 51
  • 1
  • 3
  • Can you tell me in this case how to check if the value given to a s8 (8-bit signed) if it is out of range or not. Should I compare the value to 0x7F instead of 0xFF ? And should I check first for the sign bit ? thanks – The Beast May 26 '17 at 02:01
4

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
  • 52,368
  • 9
  • 94
  • 137
  • 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 Sep 28 '10 at 11:18
  • -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 Sep 28 '10 at 11:39
  • @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 Sep 28 '10 at 12:16
  • @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 Sep 28 '10 at 12:44
  • Ok, I've actually found a copy of the standard, so I'll correct my answer. – Douglas Leeder Sep 28 '10 at 12:53
  • @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 `` offers a compliant way to define additional integer types (like, 24 or 36 bits). – DevSolar Sep 28 '10 at 12:53
  • @Jens Gustedt: I've edited my answer now I've found a reference for the C spec, is that better? – Douglas Leeder Sep 28 '10 at 13:02
  • I guess you can't use standard C on a machine with Ternary memory? – Douglas Leeder Sep 28 '10 at 13:04
  • @Douglas: great, objection removed. – Jens Gustedt Sep 28 '10 at 13:34
  • I suppose that bit operators wouldn't make much sense without binary integers. – Douglas Leeder Sep 28 '10 at 15:18
3

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
  • 54,530
  • 11
  • 89
  • 103
  • 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 Sep 28 '10 at 11:17
  • 6
    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 Sep 28 '10 at 11:24
0

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
  • 1,953
  • 2
  • 17
  • 35
  • 6
    ISO C does _not_ mandate 2's complement representation, by the way. – paxdiablo Sep 28 '10 at 11:10
  • 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 Sep 28 '10 at 11:16
  • @Anand: what do you really want? there is the bit representation (in two's complement) in the answer already. – Jens Gustedt Sep 28 '10 at 11:40
  • 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 Sep 28 '10 at 12:47
  • 'int x=5' is stored the same whether 2's, 1's, and sign/mag. In most common implementations, 'int x=-5' is stored as 2's complement, but don't depend on that for portable code. – Bill Evans at Mariposa Apr 26 '11 at 15:34