## 1.Integer Introduction

The integer type is used to represent large integers and the type declaration uses the “int” keyword.

`int a;`

The example above declares an integer variable “a”.

Different computers may have different sizes for the int data type. A common size is 4 bytes (32 bits) to store an int value, but 2 bytes (16 bits) or 8 bytes (64 bits) can also be used. The ranges of integers that they can represent are as follows:

- 16 bits: from -32,768 to 32,767.
- 32 bits: from -2,147,483,648 to 2,147,483,647.
- 64 bits: from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

## 2. signed，unsigned

In C language, the `signed`

keyword is used to indicate a type that includes negative values, while the `unsigned`

keyword indicates a type that only represents zero and positive integers.

For the `int`

type, it is by default signed, which means `int`

is equivalent to `signed int`

. Since this is the default case, the `signed`

keyword is generally omitted, but it is not incorrect to include it.

signed int a; // equals to int a;

The int type can also be used without a sign, only representing non-negative integers. In this case, the keyword unsigned must be used to declare the variable.

`unsigned int a;`

The advantage of declaring an integer variable as unsigned is that the maximum integer value that can be represented with the same length of memory is doubled. For example, the maximum value of a 16-bit signed int is 32,767, while the maximum value of an unsigned int is increased to 65,535.

The “int” inside unsigned int can be omitted, so the variable declaration above can also be written as follows:

`unsigned a;`

The `char`

type can also be declared as `signed`

or `unsigned`

. By default, `char`

is usually considered a signed type, but you can also explicitly declare it as `unsigned char`

. For example:

signed char c; // range -128 to 127 unsigned char c; // range 0 to 255

This means that in C language, whether char type is signed or unsigned is determined by the current system by default. Therefore, char is not equivalent to signed char; it could be either signed char or unsigned char.

## 3.Sub-types of Integers

Sub-Types of integers refer to derived types of basic integer types, including data types such as short, long, long long, etc.

They have different lengths and representation different ranges than int types, but they are all signed integer types. This is beneficial for more precise limitation of the range of integer variables, and also for better expression of the intention of the code.

- short int (abbr. short): occupies space no more than int, usually 2 bytes (integer range is -32768~32767).
- long int (abbr. long): occupies space not less than int, at least 4 bytes.
- long long int (abbr. long long): occupies more space than long, at least 8 bytes.

short int a; long int b; long long int c;

The above code declares variables of three integer subtypes respectively.

By default, short, long, and long long are all signed, so the signed keyword is omitted. However, they can also be declared as unsigned, which doubles the maximum value that can be represented.

unsigned short int a; unsigned long int b; unsigned long long int c;

The C language allows to omit “int”, so the variable declaration statement can also be written as follows:

short a; unsigned short a; long b; unsigned long b; long long c; unsigned long long c;

Different computers have different byte lengths for data types. If a 32-bit integer is really needed, the long type should be used instead of the int type, which can ensure no less than 4 bytes; if a 64-bit integer is really needed, the long long type should be used, which can ensure no less than 8 bytes. On the other hand, to save space, the short type should be used when only a 16-bit integer is needed, and the char type should be used when an 8-bit integer is needed.

## 4. The limit values of integer types.

The limit values of integer types refer to the maximum and minimum values that can be represented within the range of a type. In C language, the limit values of integer types can be obtained through constants defined in the header file

- CHAR_BIT: the number of bits occupied by a char type, typically 8.
- SCHAR_MAX: the maximum value of a signed char type.
- SCHAR_MIN: the minimum value of a signed char type.
- UCHAR_MAX: the maximum value of an unsigned char type.
- SHRT_MAX: the maximum value of a short type.
- SHRT_MIN: the minimum value of a short type.
- USHRT_MAX: the maximum value of an unsigned short type.
- INT_MAX: the maximum value of an int type.
- INT_MIN: the minimum value of an int type.
- UINT_MAX: the maximum value of an unsigned int type.
- LONG_MAX: the maximum value of a long type.
- LONG_MIN: the minimum value of a long type.
- ULONG_MAX: the maximum value of an unsigned long type.
- LLONG_MAX: the maximum value of a long long type.
- LLONG_MIN: the minimum value of a long long type.
- ULLONG_MAX: the maximum value of an unsigned long long type.

It should be noted that the values represented by these constants are determined at compile time and depend on the specific hardware and operating system.

Integer Data Types | Bytes | Range | Output/Input
Format Specification |
---|---|---|---|

short int | 2 | -32,768 to 32,767 | %hd |

unsigned short int | 2 | 0 to 65,535 | %hu |

unsigned int | 4 | 0 to 4,294,967,295 | %u |

int | 4 | -2,147,483,648 to 2,147,483,647 | %d |

long int | 4 | -2,147,483,648 to 2,147,483,647 | %ld |

unsigned long int | 4 | 0 to 4,294,967,295 | %lu |

long long int | 8 | -(2^63) to (2^63)-1 | %lld |

unsigned long long int | 8 | 0 to 18,446,744,073,709,551,615 | %llu |

signed char | 1 | -128 to 127 | %c |

unsigned char | 1 | 0 to 255 | %c |

float | 4 | %f | |

double | 8 | %lf | |

long double | 16 | %Lf |

We can use the` sizeof()`

function to check the byte size of each data type.

**Example 4.1 The number of bytes occupied by integer data types and the maximum and minimum values of integer types.**

#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <float.h> int main() { //for how many bytes printf("size of int : %d\n",sizeof(int)); printf("size of char : %d\n",sizeof(char)); printf("size of signed char : %d\n",sizeof(signed char)); printf("size of unsigned char : %d\n",sizeof(unsigned char)); printf("size of short : %d\n",sizeof(short)); printf("size of short int : %d\n",sizeof(short int)); printf("size of signed short : %d\n",sizeof(signed short)); printf("size of signed short int : %d\n",sizeof(signed short int)); printf("size of long int : %d\n",sizeof( long int)); printf("size of float : %d\n",sizeof(float)); printf("size of double : %d\n",sizeof(double)); printf("size of long double : %d\n",sizeof(long double)); printf("CHAR_BIT : %d\n", CHAR_BIT); //how many bits //Max Value and Min Value printf("CHAR_MAX : %d\n", CHAR_MAX); printf("CHAR_MIN : %d\n", CHAR_MIN); printf("INT_MAX : %d\n", INT_MAX); printf("INT_MIN : %d\n", INT_MIN); printf("LONG_MAX : %ld\n", (long) LONG_MAX); printf("LONG_MIN : %ld\n", (long) LONG_MIN); printf("SCHAR_MAX : %d\n", SCHAR_MAX); printf("SCHAR_MIN : %d\n", SCHAR_MIN); printf("SHRT_MAX : %d\n", SHRT_MAX); printf("SHRT_MIN : %d\n", SHRT_MIN); printf("UCHAR_MAX : %d\n", UCHAR_MAX); printf("UINT_MAX : %u\n", (unsigned int) UINT_MAX); printf("ULONG_MAX : %lu\n", (unsigned long) ULONG_MAX); printf("USHRT_MAX : %d\n", (unsigned short) USHRT_MAX); return 0; }

Results:

## 5. The Number System of Integers

In C language, integers are decimal numbers by default. To represent octal and hexadecimal numbers, special notation is required.

Octal numbers are represented with a leading zero, for example, 017 and 0377.

int a = 012; // Octal，equals to Decimal 10

Hexadecimal uses 0x or 0X as a prefix, such as 0xf, 0X10.

int a = 0x1A2B; // Hexadecimal，equals to Decimal 6699

Note that different number systems are just different ways of writing integers and do not affect the actual storage of integers. All integers are stored in binary form, regardless of the notation used.

Different number systems can be mixed, for example, 10 + 015 + 0x20 is a valid expression.

**Example 5.1 Decimal, Octal, and Hexadecimal Storage and Operations.**

#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <float.h> int main() { int x = 100; int y = 0144; printf("dec = %d\n", x); // 100 printf("octal = %o\n", x); // 144 printf("hex = %x\n", x); // 64 printf("octal = %#o\n", x); // 0144 printf("Dec x + y = %d\n", x+y); // 200 return 0; }

Example 5.1 Results:

The format specifiers related to the number system for printf() function are as follows:

- %d: Decimal integer.
- %o: Octal integer.
- %x: Hexadecimal integer (using lowercase letters).
- %X: Hexadecimal integer (using uppercase letters).
- %#o: Octal integer with a leading 0.
- %#x: Hexadecimal integer with a leading 0x (using lowercase letters).
- %#X: Hexadecimal integer with a leading 0X (using uppercase letters).

## 6. Overflow of Integer Variables

The overflow of an integer variable refers to the phenomenon that occurs when the value of an integer variable exceeds the range that its data type can represent. In C language, integer variable overflow leads to data truncation, which means discarding the part that exceeds the range, and only retaining the low-order effective part.

For example, for a signed 8-bit integer variable, its value range is from -128 to 127. If it is assigned a value of 128, it will overflow and become -128. Because in the two’s complement representation, the binary representation of 128 is 10000000, which exceeds the range that an 8-bit integer variable can represent, only the low-order effective part is retained, which is 00000000. The two’s complement of this binary number is 0, so the value of the variable becomes -128.

Similarly, if the variable is assigned a value of 129, it will become -127; if it is assigned a value of -129, it will become 127; if it is assigned a value of -130, it will become 126, and so on. This is the overflow of integer variables.

**Example 6.1 Char Type Variable Overflow**

#include <stdio.h> int main() { char a = 127; char b = a + 1; printf("a=%d\tb=%d", a,b); return 0; }

Example 6.1 Results:

`a=127 b=-128`

Process returned 0 (0x0) execution time : 0.036 s

Press any key to continue.

The reason is that the binary value of 127 is 0111 1111. When 1 is added to it, it becomes 1000 0000, which represents -128 in two’s complement. Therefore, the result is an overflow.

The following image can help to better understand integer overflow, where 127 overflows and becomes -128.

**Example 6.2 Integer Type Variable Overflow**

#include <stdio.h> int main() { int a, b; a=2147483647; b=a+1; printf("%d, %d\n",a,b); return 0; }

**Example 6.2 Results**

`2147483647, -2147483648`

Process returned 0 (0x0) execution time : 0.587 s

Press any key to continue.

variable a in binary number system is : `01111111 11111111 11111111 11111111`

plus 1 and becomes `10000000 00000000 00000000`

Actually is is overflowed.

wer