How are integers stored in memory using two’s complement?

Estefano Misme
5 min readAug 9, 2021

The two’s complement of a number is a method that indicates how far that number takes to reach 2^n, where n is an arbitrary number of bits where the number will be written in the binary system.

int a = 5;
int n = 3;
// the two’s complement of 'a', for n = 3 is 3 because 2^3 - 5 = 3

The system uses this operation to distinguish between positive and negative integers. Regardless of the amount of bits you are using , the system takes the first digit of the block reserved bits in memory to see if the integer is negative or positive. If this digit is zero (0), it will recognize the integer as positive. If the digit is one (1), it will recognize it as negative.

int a = 45;   // binary = 00101101 -> first digit = 0, then a is positive
int b = -45; // binary = 11010011 -> first digit = 1, then b is negative

The two’s complement of a number is calculated in the system as follows:

  1. The number is “converted” to the binary system.
  2. Once converted to binary, the digits of the number are inverted . If it contains a 1, it will be set to zero, and vice versa. This is known as one’s complement.
  3. Add 1 to the resulting number.
int a = -45;
/**
* absolute value = 45 -> binary = 00101101
* converting 45 in negative
* -> one's complement(00101101): 11010010 +
* -> add one to the result: 1 = 11010011
*/

This method of conversion, unlike formerly used by other operating systems, avoids repeating the zero mark, as it does the method sign -and- magnitude . It only uses zero once, taking it as positive, which causes it to leave an additional value available for negative numbers. Positive numbers range from 0 to 2 n -1 while negative numbers range from -1 to -1 * (2^n).

|INT_MIN| = INT_MAX + 1 //this is not a code line, just an affirmation

This also causes the zero and the maximum negative value to be the exceptions to the two’s complement rule to be stored in memory. Zero uses (000… 000), while negative maximum value uses (100… 000).

Next, we will show you a table showing the representation of positive and negative numbers in a 4-bit space through two’s complement.

Now let’s get down to business. The explanation at the beginning of the topic could not be very clear when taking an as “an arbitrary amount of bits where the number will be written in the binary system “. If we declare a variable, for example, in the C language, for an int ( integer ) , the system will reserve 4 bytes in memory to store this integer. Each byte contains 8 bits, so a total of 32 bits would be reserved for this integer. This amount of bits is what we will use to write the assigned integer. You can represent 2^32 integers in this statement.

int a = 25;                  // 1 byte   1 byte   1 byte   1 byte
//binary(for 32 bits alloc) = 00000000 00000000 00000000 00011001
//negative representation = 11111111 11111111 11111111 11100111

If the variable were a short int , which reserves only 2 bytes , it would only take 16 memory spaces to display the integers. Then a maximum of 2^16 integers can be represented .

short int a = 25;            // 1 byte   1 byte
//binary(for 16 bits alloc) = 00000000 00011001
//negative representation = 11111111 11100111

However, if it were a long int , which reserves 8 bytes, 64 bits of memory will be allocated. A maximum of 2^64 integers can be represented .

long int a = 25;/**
* 1 byte 1 byte 1 byte 1 byte 1 byte 1 byte 1 byte 1 byte
* binary (for 64 bits alloc):
* 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00011001
* negative representation:
* 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11100111

Overflow.

We need to warn you of something . If the value of the integer that we are declaring is greater than the limit limited by the type declaration, then an overflow error will occur and the program won’t process all the bits of the number.

#include <stdio.h>int main()
{
short int sh = 75536;
printf("%d", sh);
return 0;
}

Output:

main.c:5:20: warning: overflow in implicit constant conversion [-Woverflow]
short int sh = 75536;
^~~~~
10000

Synthesis.

So the whole process of storing and handling integers boils down to the following:

- An integer is declared in a specific format (int , long or short).

- The system will reserve as many bits in memory as the size (in bytes) of the type that we assign to the integer specifies.

- The system works with the integer as if it were a binary number.

- If it detects a negative sign, it converts the integer to its two’s complement.

- If the value of the integer is larger than the maximum limit or smaller than the minimum limit of its declared type, an overflow error occurs and the program will work with errors. Otherwise, the program continues sucessfully.

- Then the integer managed to be stored correctly in the system memory.

Unsigned integers.

If an unsigned integer (declaring unsigned [other] int ) is declared, an important change willbe made in this process: because the statement this time will not represent negative numbers because of its property of “unsigned” the system It will no longer take the first digit stored in memory as a sign, but will be directly part of the binary number. Signed integers, due they need to reserve a bit for the sign, they cannot support a quantity with an absolute value as large as an unsigned integer can.

For the case of an int declaration , if we reserve 32 bits of memory, the minimum and maximum quantities that can be represented will range between (2^31)-1 and (-1) * 2^31 , while with an unsigned int , it will be possible to represent the numbers from 0 to (2 ^32)-1.

Example with signed integer:

#include <stdio.h>
#include <math.h>
int main()
{
int ui = pow(2, 31) + 235478;
printf("%u", ui);
return 0;
}

Output:

main.c:6:14: warning: overflow in implicit constant conversion [-Woverflow]
int ui = pow(2, 31) + 235478;
^~~
2147483647

Example with unsigned integer:

#include <stdio.h>
#include <math.h>
int main()
{
unsigned int ui = pow(2, 31) + 235478;
printf("%u", ui);
return 0;
}

Output: 2147719126

--

--