What is the difference between "long", "long long", "long int", and "long long int" in C++?

Learn what is the difference between "long", "long long", "long int", and "long long int" in c++? with practical examples, diagrams, and best practices. Covers c++, long-integer development techniq...

Understanding C++ Integer Types: long, long long, long int, and long long int

Diagram illustrating different sizes of integer types in C++ memory

Explore the nuances of C++ integer types, specifically 'long', 'long long', 'long int', and 'long long int', to understand their sizes, ranges, and appropriate use cases across different platforms.

In C++, choosing the correct integer type is crucial for memory efficiency, performance, and preventing overflow errors. While int is the most common integer type, C++ offers several variations to handle larger numbers or ensure specific memory footprints. This article delves into the distinctions between long, long long, long int, and long long int, clarifying their standard guarantees and typical implementations.

The C++ Standard and Integer Type Guarantees

The C++ standard (and C standard, from which these types originate) defines minimum size requirements for integer types but allows implementations to use larger sizes. This flexibility means that the exact size of long or int can vary between compilers and architectures (e.g., 32-bit vs. 64-bit systems). However, a few key relationships are guaranteed:

  • sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
  • Each type must be able to hold at least the range specified by the standard.

Let's break down each type.

flowchart TD
    A[Integer Type Declaration] --> B{Is 'long' specified?}
    B -->|Yes| C{Is 'long long' specified?}
    B -->|No| D[Default 'int']
    C -->|Yes| E["long long (int)" - At least 64 bits]
    C -->|No| F["long (int)" - At least 32 bits]
    D --> G["int" - At least 16 bits]
    E --> H[Largest Range]
    F --> I[Medium Range]
    G --> J[Smallest Range]

Decision flow for C++ integer type selection based on 'long' keywords.

long and long int

The long keyword, when used alone, is a shorthand for long int. Both long and long int refer to the same data type. The C++ standard guarantees that long will be at least 32 bits wide. On most modern 64-bit systems, long is typically 64 bits, matching the size of a pointer. However, on 32-bit systems, it's usually 32 bits. This variability is a key point to remember when writing portable code.

#include <iostream>

int main() {
    long a = 1234567890L; // 'L' suffix for long literal
    long int b = 9876543210L;

    std::cout << "Size of long: " << sizeof(a) << " bytes\n";
    std::cout << "Size of long int: " << sizeof(b) << " bytes\n";
    std::cout << "Value of a: " << a << "\n";
    std::cout << "Value of b: " << b << "\n";

    return 0;
}

Demonstrates long and long int usage and their typical size.

long long and long long int

Similar to long and long int, long long is a shorthand for long long int. This type was introduced in C++11 (and C99) to provide a guaranteed minimum size of 64 bits, regardless of the system architecture. This makes long long the preferred choice when you need to store very large integer values and require consistent behavior across different platforms. It is guaranteed to be at least as large as long.

#include <iostream>
#include <limits>

int main() {
    long long c = 1234567890123456789LL; // 'LL' suffix for long long literal
    long long int d = -9876543210987654321LL;

    std::cout << "Size of long long: " << sizeof(c) << " bytes\n";
    std::cout << "Size of long long int: " << sizeof(d) << " bytes\n";
    std::cout << "Value of c: " << c << "\n";
    std::cout << "Value of d: " << d << "\n";
    std::cout << "Max value of long long: " << std::numeric_limits<long long>::max() << "\n";

    return 0;
}

Illustrates long long and long long int usage, their guaranteed 64-bit size, and maximum value.

Summary of Differences and Best Practices

The primary difference lies in their guaranteed minimum sizes and platform-dependent behavior. Here's a quick recap:

  • int: At least 16 bits. Typically 32 bits on modern systems.
  • long / long int: At least 32 bits. Often 64 bits on 64-bit systems, 32 bits on 32-bit systems.
  • long long / long long int: At least 64 bits. Guaranteed 64 bits on all modern systems.

When to use which:

  • Use int for general-purpose integer arithmetic where the values are unlikely to exceed ±2 billion.
  • Use long if you need a larger range than int and are comfortable with its size potentially varying between 32 and 64 bits depending on the platform. Be cautious with portability.
  • Use long long when you absolutely need a 64-bit integer, such as for very large counts, timestamps, or cryptographic operations, and require consistent behavior across all platforms. This is the most portable choice for large integers.

Table comparing C++ integer types: int, long, long long, with their minimum sizes and typical sizes on 32-bit and 64-bit systems.

Comparison of C++ integer types: int, long, and long long.

For maximum portability and explicit size control, consider using fixed-width integer types from the <cstdint> header, such as int32_t, int64_t, uint32_t, uint64_t, etc. These types guarantee a specific bit width, removing ambiguity across different compilers and architectures.