Visrut
Visrut

Reputation: 671

How does c language store int in memory?

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *p_x = (int *)malloc(1 * sizeof(int));
    scanf("%d", p_x);

    for (int i = 0; i < 4; i++) {
        char *one_byte_slice = (((char *)(p_x)) + i);
        printf("slice : %d , value : %d\n", i, *one_byte_slice);
    }
    return 0;
}

When I entered positive values they seems understandable to me but for negative I don't understand it well.

For *p_x = 127:

127
slice : 0 , value : 127
slice : 1 , value : 0
slice : 2 , value : 0
slice : 3 , value : 0

p_x  --->  0111 1111
           0000 0000
           0000 0000
           0000 0000

For *p_x = 256:

256
slice : 0 , value : 0
slice : 1 , value : 1
slice : 2 , value : 0
slice : 3 , value : 0

p_x  --->  0000 0000
           0000 0001
           0000 0000
           0000 0000

For *p_x = -20:

-20
slice : 0 , value : -20
slice : 1 , value : -1
slice : 2 , value : -1
slice : 3 , value : -1

p_x  --->  1001 0100
           1000 0001
           1000 0001
           1000 0001

And for *p_x = -256:

-256
slice : 0 , value : 0
slice : 1 , value : -1
slice : 2 , value : -1
slice : 3 , value : -1

p_x  --->  0000 0000
           1000 0001
           1000 0001
           1000 0001

So how is it stored in memory for fixed point numbers is is stored in 2's complement or other way?

Upvotes: 1

Views: 955

Answers (2)

Luis Colorado
Luis Colorado

Reputation: 12668

This is called low-endian encoding. The individual bit slices of the integer are stored from least significative to most significative in the consecutive byte cells. Your integer is represented in binary form as:

0000 0000 0000 0000 0000 0000 0111 1111

(where I have used a space to separate each group of four bits). Each byte is stored from the least significant group of eight bits to the most, in growing byte addresses, starting from the right above:

Addr.  Value.
0000: 0111 1111
0001: 0000 0000
0002: 0000 0000
0003: 0000 0000

There's another way to do it, which is called big-endian, which stores the bytes just in the reverse direction, and some machines do it:

(Big-endian)
Addr.  Value.
0000: 0000 0000
0001: 0000 0000
0002: 0000 0000
0003: 0111 1111

There are other ways to do, but today's computers normally use one of these two.

In the case of negative numbers, the solution consists in thinking that negative numbers and positive numbers are so that adding and subtrating can be done withou having to use an alternate circuitry. So numbers are divided in two halves and the ones with the most significant bit represent the negative ones... so numbers are represented (I'll use only four bits for brevity):

1000: -8
1001: -7
1010: -6
1011: -5
1100: -4
1101: -3
1110: -2
1111: -1
0000: 0
0001: 1
0010: 2
0011: 3
0100: 4
0101: 5
0110: 6
0111: 7

With 32 bits the result is the same, but extended to 32 bits... this makes that all the small negative numbers have all the most significant bits equal to 1.

1000 0000 0000 0000: -2147483648
1000 0000 0000 0001: -2147483647
...
1111 1111 1111 1101: -3
1111 1111 1111 1110: -2
1111 1111 1111 1111: -1
0000 0000 0000 0000: 0
0000 0000 0000 0001: 1
...
0111 1111 1111 1100: 2147483644
0111 1111 1111 1101: 2147483645
0111 1111 1111 1110: 2147483646
0111 1111 1111 1111: 2147483647

in such a way that adding is jumping in the previous table downwards and subtracting going upwards. This is called two's complement encoding.

Upvotes: 1

Visrut
Visrut

Reputation: 671

Yeah i think i got my answer.

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *p_x = (int *) malloc(1*sizeof(int));
    scanf("%d",p_x);

    for(int i=0;i<4;i++) {
        unsigned char *one_byte_slice = ( ((unsigned char *)(p_x)) + i);
        printf("slice : %d , value : %hhx\n",i,*one_byte_slice);
    }
    return 0;
}

When i tried %hhx and unsigned char * it's shows me 2's complement for negative values.

-1
slice : 0 , value : ff
slice : 1 , value : ff
slice : 2 , value : ff
slice : 3 , value : ff


p_x  --->  1111 1111
           1111 1111
           1111 1111
           1111 1111
-3
slice : 0 , value : fd
slice : 1 , value : ff
slice : 2 , value : ff
slice : 3 , value : ff

p_x  --->  1111 1101
           1111 1111
           1111 1111
           1111 1111

Yeah so conclusion is it's stored in 2's complement format.

Upvotes: 0

Related Questions