What are integers?

An integer is a type that represents whole numbers - both positive and negative - as well as zero. Examples include -15, -1, 0, 7, and 834. C++ provides four fundamental integer types:

Type Minimum Size Notes
short 16 bits
int 16 bits Usually 32 bits on modern systems
long 32 bits
long long 64 bits

The primary difference between these types is their size, which determines the magnitude of numbers they can represent.

Remember
C++ guarantees only minimum sizes for integer types, not specific sizes. Actual sizes vary by system and compiler. Use the sizeof operator to check your specific system.

Understanding signed integers

In everyday notation, we indicate negative numbers with a minus sign: -7 means "negative seven." This property of being positive, negative, or zero is called the number's sign.

In C++, integers are signed by default. This means they store the sign along with the value, allowing them to represent positive numbers, negative numbers, and zero.

Declaring signed integers

Here's the recommended syntax for declaring signed integers:

short s{};
int i{};
long l{};
long long ll{};

While short int, long int, and long long int are valid, prefer the shorter forms. Avoid using the signed keyword - it's redundant since integers are signed by default.

Best Practice
Use the short forms without the int suffix or signed prefix.

Signed integer ranges

The set of possible values a type can represent is called its range. For integers, the range depends on size (in bits) and whether the type is signed.

Size Range
8-bit signed -128 to 127
16-bit signed -32,768 to 32,767
32-bit signed -2,147,483,648 to 2,147,483,647
64-bit signed -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

An n-bit signed integer has a range of -(2^(n-1)) to (2^(n-1))-1.

Integer overflow

What happens when you try to store a value outside an integer's range? This situation is called overflow, and for signed integers, it causes undefined behavior.

#include <iostream>

int main()
{
    int maximum{2'147'483'647};  // largest value for 4-byte signed int
    std::cout << maximum << '\n';

    maximum = maximum + 1;  // overflow! undefined behavior
    std::cout << maximum << '\n';

    return 0;
}

On one test system, this produced:

2147483647
-2147483648

However, since the second value results from undefined behavior, you might see different output on your system.

Warning
Overflow causes data loss. If you suspect a variable might need to store values outside its type's range, choose a larger type.

Integer division behavior

When dividing two integers, C++ always produces an integer result. The fractional portion is discarded - not rounded!

#include <iostream>

int main()
{
    std::cout << 17 / 4 << '\n';  // outputs 4, not 4.25
    return 0;
}

Mathematically, 17 / 4 equals 4.25. The fractional part (0.25) is dropped, leaving 4. Similarly, -17 / 4 produces -4.

Warning
Be cautious with integer division, as fractional parts are lost. If you need fractional results, use floating-point types.