Data Types Deep Dive — Choosing the Right Box
Learn why picking the right data type matters — and how overflow can silently destroy your CP solutions!
Open interactive version (quiz + challenge)Real-world analogy
Data types are like different-sized boxes. An 'int' is a medium box that holds numbers up to about 2 billion. A 'long long' is a giant crate that holds numbers up to 9 quintillion. A 'double' is a special box that can hold numbers with decimal points. If you try to stuff a giant number into a medium box, it OVERFLOWS — like trying to pour a swimming pool into a teacup. The water spills and you get garbage!
What is it?
Data types tell C++ what kind of value a variable holds and how much memory to reserve. Choosing the right type is crucial in CP — too small and you get overflow bugs, too big and you waste memory. The main types are int, long long, double, char, string, and bool.
Real-world relevance
Data types matter everywhere in computing. Banks use precise types for money (you do not want rounding errors with someone's salary!). Video games use different types for health (int), position (double), and alive/dead (bool). In CP, the wrong data type is the difference between Accepted and Wrong Answer.
Key points
- int — Your Everyday Number Box — An 'int' stores whole numbers from about -2 billion to +2 billion (exactly -2,147,483,648 to 2,147,483,647). That is roughly ±2 × 10^9. For most CP problems, int is enough. It uses 4 bytes (32 bits) of memory. Think of it as your go-to type — use int unless you have a reason not to!
- long long — The Giant Number Crate — A 'long long' stores whole numbers up to about ±9.2 × 10^18 (that is 9 quintillion — a number with 18 zeros!). It uses 8 bytes (64 bits). In CP, MANY problems need long long because they multiply big numbers or add lots of things. Rule of thumb: if a problem says n can be up to 10^9, and you multiply two of them, the result can be 10^18 — you NEED long long!
- Overflow — The Silent Killer — Overflow happens when a number gets too big for its type. If an int holds 2,147,483,647 and you add 1, it wraps around to -2,147,483,648! The program does NOT crash or warn you — it just gives wrong answers silently. This is the #1 sneaky bug in CP. You submit, get Wrong Answer, and spend an hour debugging when the fix is just changing int to long long!
- double — The Decimal Box — A 'double' stores decimal (floating-point) numbers like 3.14159 or -0.001. It can hold very large and very small numbers, but it is not perfectly precise — 0.1 + 0.2 might give 0.30000000000004 instead of exactly 0.3! In CP, use double when the problem specifically asks for decimal output. Otherwise, stick to integers.
- Type Casting — Changing Boxes — You can convert between types using casting. (int)3.7 gives 3 (chops off the decimal, does NOT round). (double)5 / 2 gives 2.5 (forces decimal division). (long long)a * b does the multiplication with big numbers. Casting is your tool for telling C++: 'Hey, treat this number differently for a moment!'
- When to Use What — The CP Cheat Sheet — Use 'int' for numbers up to about 2 billion. Use 'long long' when: the problem has numbers > 10^9, or you multiply/add numbers that could exceed 2 billion, or the problem says 'print answer modulo 10^9+7' (intermediate values might be huge). Use 'double' only when the problem asks for decimal output.
- char and string — Text Types — A 'char' holds a single character like 'A' or '7'. A 'string' holds a sequence of characters like 'hello'. Characters have numeric values (ASCII): 'A' is 65, 'a' is 97, '0' is 48. This is useful in CP — you can do math with characters! 'a' + 1 gives 'b'. We will use these more in later lessons.
- bool — True or False — A 'bool' holds either true or false. It uses just 1 byte. You will use bools for flags: bool found = false; then later found = true; when you discover something in your search. In C++, true is treated as 1 and false as 0, so you can even do math with them!
Code example
#include <bits/stdc++.h>
using namespace std;
int main() {
// int: up to ~2 billion
int a = 1000000000; // 1 billion — fits in int
// int overflow example:
// int bad = a * 3; // OVERFLOW! 3 billion > int max
// long long: up to ~9.2 * 10^18
long long big = (long long)a * 3; // Cast BEFORE multiply!
cout << "big = " << big << "\n"; // 3000000000
// double: decimal numbers
double pi = 3.14159265358979;
cout << fixed << setprecision(6) << pi << "\n"; // 3.141593
// Integer division vs real division
int x = 5, y = 2;
cout << x / y << "\n"; // 2 (integer division)
cout << (double)x / y << "\n"; // 2.5 (real division)
// Type casting: double to int truncates
double d = 3.99;
int truncated = (int)d;
cout << truncated << "\n"; // 3 (NOT 4! it chops, not rounds)
// Checking overflow: max values
cout << "int max: " << INT_MAX << "\n"; // 2147483647
cout << "long long max: " << LLONG_MAX << "\n"; // 9223372036854775807
return 0;
}Line-by-line walkthrough
- 1. int a = 1000000000; — we store 1 billion in an int. This fits fine because int can hold up to about 2.1 billion.
- 2. // int bad = a * 3; — DO NOT do this! 1 billion × 3 = 3 billion, which is bigger than int's max of ~2.1 billion. This would overflow and give a wrong negative number.
- 3. long long big = (long long)a * 3; — the (long long) cast converts a to a long long BEFORE the multiplication happens. Now the math is done in long long space, and 3 billion fits perfectly.
- 4. cout << big; — prints 3000000000. Without the cast, this would have printed a garbage negative number!
- 5. double pi = 3.14159265358979; — we store pi in a double. Doubles can hold about 15-16 significant digits.
- 6. cout << fixed << setprecision(6) << pi; — prints 3.141593 with exactly 6 decimal places.
- 7. cout << x / y; — integer division: 5/2 = 2. The .5 is thrown away because both x and y are int.
- 8. cout << (double)x / y; — casting x to double forces real division: 5.0/2 = 2.5.
- 9. int truncated = (int)d; — converting 3.99 to int gives 3. It CHOPS the decimal, it does NOT round up!
- 10. cout << INT_MAX; — prints 2147483647, the largest number an int can hold. Know this number — it will save you from overflow bugs!
Spot the bug
#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b;
cin >> a >> b;
int product = a * b;
cout << product << "\n";
return 0;
}Need a hint?
If a and b can each be up to 1,000,000,000 (10^9), what happens when you multiply them and store the result in an int?
Show answer
The bug is overflow! If a = 1000000000 and b = 3, then a * b = 3000000000, which exceeds the int maximum of 2147483647. The result wraps around to a negative number. The fix: change 'int product' to 'long long product' AND cast before multiplying: long long product = (long long)a * b; — the cast ensures the multiplication itself happens in long long.
Explain like I'm 5
Imagine you have three piggy banks: a small one (int) that holds up to 2 billion coins, a HUGE one (long long) that holds 9 quintillion coins, and a magic one (double) that can hold half-coins and quarter-coins. If you try to put too many coins in the small piggy bank, they spill out and you lose count — that is overflow! Always pick a piggy bank big enough for your coins.
Fun fact
The number 2,147,483,647 (the maximum int value) is actually a prime number! It is 2^31 - 1, also called a Mersenne prime. CP contestants have this number practically tattooed on their brains because hitting it means overflow. Pro tip: if your answer should be positive but you see negative numbers appearing, overflow is almost certainly the culprit!
Hands-on challenge
Write a program that reads two integers a and b (each up to 10^9). Print their product. Be careful — the product of two numbers up to 10^9 can be up to 10^18, which overflows int! Make sure you use the right data type. Test with a=1000000000, b=3. You should get 3000000000, not a weird negative number.
More resources
- CP-Algorithms — Data Types and Overflow (CP-Algorithms)
- C++ Data Types for Competitive Programming (YouTube)
- Codeforces — Way Too Long Words (Codeforces)