Skip to content

Commit 3378c40

Browse files
committed
docs(numeric): Add Documentation Page: 'Working with 128-bit Integers in C++'
1 parent 8969b88 commit 3378c40

File tree

2 files changed

+102
-1
lines changed

2 files changed

+102
-1
lines changed

misc/misc_cond.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ template<typename T>
22
inline bool between(T a, T b, T c) { return (a <= b && b <= c); }
33
// #define between(a, b, c) ((a) <= (b) && (b) <= (c))
44
#define has_key(it, key) (it.find(key) != it.end())
5-
#define check_coord(x, y, n, m) (0 <=x && x < n && 0 <= y && y < m)
5+
#define check_coord(x, y, n, m) (0 <= (x) && (x) < (n) && 0 <= (y) && (y) < (m))
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
sidebar_position: 4
3+
title: Working with 128-bit Integers in C++
4+
sidebar_label: Working with 128-bit Integers
5+
---
6+
7+
## What this code does (short)
8+
9+
The code defines a 128-bit integer type for GNU C++ (`__int128`) and provides two stream operators so you can use `cin >>` and `cout <<` with that type. This is useful because the standard iostream library does not know how to read or print `__int128`.
10+
11+
---
12+
13+
## Line-by-line explanation
14+
15+
```cpp
16+
// for: GNU C++20 (64)
17+
using i128 = __int128;
18+
const i128 ONE_128 = i128(1);
19+
const i128 ZERO_128 = i128(0);
20+
```
21+
22+
* `using i128 = __int128;` creates an alias `i128` for the builtin GNU type `__int128`.
23+
* `__int128` is a 128-bit signed integer available in GNU compilers on 64-bit systems. It stores much bigger values than `long long`.
24+
25+
* These two lines define constants `ONE_128` and `ZERO_128` with values `1` and `0` typed as `i128`.
26+
* They make the code clearer when you need literal 128-bit constants.
27+
28+
---
29+
30+
### Input operator: `operator >>`
31+
32+
```cpp
33+
std::istream &operator>>(std::istream &is, i128 &n) {
34+
n = 0;
35+
std::string s; is >> s;
36+
for (auto c : s) {
37+
n = 10 * n + c - '0';
38+
}
39+
return is;
40+
}
41+
```
42+
43+
* This overload lets you write `cin >> my_i128_variable;`.
44+
45+
* Steps it performs:
46+
47+
1. Set `n` to zero.
48+
2. Read the whole token from the stream into a `std::string s`. This skips leading whitespace and reads until the next whitespace.
49+
3. For each character `c` in the string, it updates `n = 10*n + (c - '0')`. That converts the decimal digits to a numeric value.
50+
4. Return the input stream reference so chaining (e.g., `cin >> a >> b;`) works.
51+
52+
* **Important limitations**:
53+
54+
* The code assumes the string contains only digits (`'0'``'9'`). It does **not** handle a leading `-` sign, a leading `+`, or invalid characters.
55+
* It does not check for overflow. If the number in the input is larger than 128 bits can hold, the behavior is undefined (it will wrap or give wrong results).
56+
57+
---
58+
59+
### Output operator: `operator <<`
60+
61+
```cpp
62+
std::ostream &operator<<(std::ostream &os, i128 n) {
63+
if (n == 0) {
64+
return os << 0;
65+
}
66+
std::string s;
67+
while (n > 0) {
68+
s += '0' + n % 10;
69+
n /= 10;
70+
}
71+
std::reverse(s.begin(), s.end());
72+
return os << s;
73+
}
74+
```
75+
76+
* This overload lets you write `cout << my_i128_variable;`.
77+
78+
* Steps it performs:
79+
80+
1. If `n` is zero, it prints `0` and returns.
81+
2. Otherwise it builds a string `s` with the digits of `n` in reverse order: take `n % 10` to get the last digit, append the corresponding character, and then divide `n` by 10.
82+
3. Reverse the string to get the correct digit order.
83+
4. Output the string and return the stream.
84+
85+
**⚠️ Warning:**
86+
*The provided code only works correctly for **positive integers**. It does **not** support negative numbers or the sign `-`, and printing a negative `i128` will also produce incorrect output.*
87+
88+
* **Important limitations**:
89+
90+
* The code assumes `n` is non-negative. If `n` is negative, the `while (n > 0)` loop never runs and the result is wrong. Typical fix: check `if (n < 0) { os << '-'; n = -n; }` before converting digits.
91+
* Converting a 128-bit integer to decimal takes time proportional to the number of digits (about 39 digits max for 128-bit), which is fine for competitive programming.
92+
93+
---
94+
95+
## How to use
96+
97+
```cpp
98+
i128 a;
99+
cin >> a;
100+
cout << a << '\n';
101+
```

0 commit comments

Comments
 (0)