long long - 64-bit Integer Type
long long is a 64-bit integer type introduced in C++11, used to represent larger range integer values. It solves the range limitation issues of traditional integer types when representing large integers.
| Book | Video | Code | X |
|---|---|---|---|
| cppreference / markdown | Video Explanation | Practice Code |
Why was it introduced?
- Solve the insufficient range of traditional integer types
- Provide a unified 64-bit integer type standard
What's the difference between long long and traditional integer types?
long longguarantees at least 64-bit width, with range at least from -2^63 to 2^63-1intis typically 32-bit, with range approximately -2.1 billion to 2.1 billionlongis 32-bit on 32-bit systems, typically 64-bit on 64-bit systems (but standard only guarantees at least 32-bit)
I. Basic Usage and Scenarios
Basic Declaration and Initialization
Support for signed and unsigned versions, with literal suffixes
// Signed long long
long long val1 = 1;
long long val2 = -1;
// Unsigned long long
unsigned long long uVal1 = 1;
// Literal identifiers + type deduction
auto longlong = 1LL;
auto ulonglong = 1ULL;
Large Integer Applications and Boundary Values
Handle calculations beyond traditional integer type ranges, based on boundary value acquisition
//#include <limits>
// Using long long for large number calculations (exceeding int range)
long long population = 7800000000LL; // World population
// Get integer type boundaries
int maxInt = std::numeric_limits<int>::max();
long long maxLL = std::numeric_limits<long long>::max();
auto minLL = std::numeric_limits<long long>::min();
II. Important Notes
Type Deduction and Literal Suffixes
Use LL or ll suffix to explicitly specify long long literals, use ULL or ull to specify unsigned versions
auto num1 = 10000000000; // Type may be int or long, depending on compiler
auto num2 = 10000000000LL; // Explicitly long long to assist type deduction
Type Conversion and Precision Issues
Be aware of precision loss that may occur during conversions between different integer types
long long bigValue = 3000000000LL;
int smallValue = bigValue; // May overflow
std::cout << "bigValue: " << bigValue << std::endl;
std::cout << "smallValue: " << smallValue << std::endl; // May be incorrect
// Safe conversion check
if (bigValue > std::numeric_limits<int>::max() || bigValue < std::numeric_limits<int>::min()) {
std::cout << "Conversion would cause overflow!" << std::endl;
}
Bit-Width Confusion - Why Doesn't the Standard Fix the Bit Width?
Reasons
- Hardware Variations: Different architectures have different "natural word sizes," such as 16/32/64 bits, and many embedded systems only support 8/16-bit multiplication and division instructions. If
longwere forcibly defined as 64 bits, it would cause significant performance issues on some machines (e.g., 32-bit MCUs).- For example: Performing 64-bit calculations on an 8-bit machine without relevant hardware instructions would require algorithmic simulation, leading to a sharp increase in
instruction cycles.
- For example: Performing 64-bit calculations on an 8-bit machine without relevant hardware instructions would require algorithmic simulation, leading to a sharp increase in
- Historical and ABI Compatibility: C/C++ predates the widespread adoption of modern 32/64-bit systems. Many platforms have system interfaces, file formats, and calling conventions that have already encoded the size of
int/longinto their ABI. Forcing a change in the standard would break binary compatibility and disrupt the ecosystem. - Zero-Cost Abstraction: The C/C++ standard is designed to map efficiently to the underlying hardware. It only specifies behavior and minimum ranges, allowing implementations to choose the most natural width for the platform, thereby achieving zero-cost or near-zero-cost abstraction.
Solutions
- Optional Fixed-Width Types in C/C++: When precise bit widths are required, use types from
<cstdint>/<stdint.h>such asint8_t,int16_t,int32_t,int64_t, etc. - Avoid Bit-Width Assumptions and Use Static Assertions: Avoid assuming the bit width of types during development to improve portability. If certain code relies on specific bit-width assumptions, use static assertions to ensure the width meets expectations:
static_assert(sizeof(T) == N).

III. Practice Code
Practice Code Topics
Auto-Checker Command
d2x checker long-long