uint128: the 128-bit unsigned integer
uint128 holds every whole number from 0 to 2¹²⁸ − 1, about 3.40 × 10³⁸, none of them negative. The exact maximum, all 39 digits, is below.
uint128 limits
- Maximum
- 340,
282, 366, 920, 938, 463, 463, 374, 607, 431, 768, 211, 455 power2¹²⁸ − 1hex0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFbinary1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 - Minimum
- 0power0hex0x00000000000000000000000000000000binary0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
- Distinct values
- 2¹²⁸ = 340,
282, 366, 920, 938, 463, 463, 374, 607, 431, 768, 211, 456 - Size
- 128 bits, 16 bytes
uint128 overflow playground
Starts at the maximum, one step from overflowing. Change the operation, the value or the type, or cast to another width, and watch the bits wrap.
Decimal, 0x hex or 0b binary, with a minus sign if negative. 2^31 − 1 works too.
Struck-through bits are dropped.
- Exact answer: 340,
282, 366, 920, 938, 463, 463, 374, 607, 431, 768, 211, 456. - That is above the maximum of uint128, 340,
282, 366, 920, 938, 463, 463, 374, 607, 431, 768, 211, 455. - The hardware keeps only the low 128 bits, which is the same as taking the answer modulo 2¹²⁸ = 340,
282, 366, 920, 938, 463, 463, 374, 607, 431, 768, 211, 456: 0.
What uint128 is called in each language
| Language | Type | Limits in code | Note |
|---|---|---|---|
| C and C++ | unsigned __int128 | Not standard: a GCC and Clang extension on 64-bit targets, with no limit macros. | |
| Java | none | Use java.math.BigInteger. | |
| C# | UInt128 | UInt128.MaxValue | .NET 7 and later. |
| Rust | u128 | u128::MAX | |
| Go | none | Use math/big. | |
| Swift | UInt128 | UInt128.max | Swift 6 and later. |
| Kotlin | none | Use java.math.BigInteger on the JVM. | |
| MySQL | none | Use DECIMAL(39, 0) for whole numbers this big. | |
| PostgreSQL | none | Use numeric; a 128-bit identifier fits the uuid type. | |
| SQL Server | none | Use decimal(38, 0), which stops one digit short; uniqueidentifier is 128 bits. | |
| JavaScript | none | BigInt has no fixed width; BigInt.asUintN(128, x) wraps a value into 128 bits. | |
| Python | none | Python’s own int holds any size. |
Only names with exactly 128 bits on every platform are listed as the type.
What happens when uint128 overflows
In 128 bits, 340,
BigInt.asUintN(128, 340282366920938463463374607431768211455n + 1n) → 0n
Whether a program is allowed to wrap like that depends on the language:
| Language | By default | To check or wrap on purpose |
|---|---|---|
| C and C++ | Unsigned types wrap around modulo 2ⁿ. Signed overflow is undefined behaviour: the compiler may assume it never happens and optimise on that basis. Types narrower than int are promoted to int first, so even uint16_t × uint16_t can overflow a signed int. | __builtin_add_overflow (GCC, Clang); ckd_add in C23’s <stdckdint.h>; -fsanitize=undefined to catch it |
| Java | Wraps around silently, in two’s complement. | Math.addExact, multiplyExact and friends throw ArithmeticException |
| C# | Wraps around, unless the code is in a checked context, which throws OverflowException. A constant expression that overflows is a compile error. | checked(...) blocks, or the CheckForOverflowUnderflow compiler option |
| Rust | Panics in debug builds. Release builds wrap, unless overflow-checks is turned on for that profile. | checked_add, wrapping_add, saturating_add, overflowing_add |
| Go | Wraps around silently. Only constant expressions that overflow are compile errors. | math/bits.Add64 reports the carry; Mul64 returns the high half of the product |
| Swift | Traps: the program stops with a runtime error. | &+, &-, &* wrap on purpose; addingReportingOverflow reports it |
| Kotlin | Wraps around silently, like Java. | Math.addExact on the JVM |
| JavaScript | Numbers never wrap, but lose precision past 2⁵³. Bitwise operators and typed arrays wrap to their width. BigInt never overflows. | Number.isSafeInteger; BigInt.asIntN and asUintN to wrap deliberately |
| Python | int never overflows: it grows as needed. | ctypes and NumPy fixed-width types do wrap |
| SQL | An error: the statement fails with an out of range or arithmetic overflow message. | MySQL outside strict mode clips an out-of-range value stored into a column to the limit, with a warning |
Common mistakes with uint128
- Counting down to zero with an unsigned counter. A loop such as for (i = n; i >= 0; i--) never ends when i is uint128: i >= 0 is always true, and 0 − 1 wraps to 340,
282, 366, 920, 938, 463, 463, 374, 607, 431, 768, 211, 455. Test i > 0 and use i − 1 inside, or use a signed counter. - Expecting the usual tools to handle 128 bits. GCC and Clang have no literal for __int128 and printf has no format for it, so build values from two 64-bit halves and print them yourself. MySQL, PostgreSQL and SQL Server have no 128-bit integer column type either.
Where you meet uint128
- An IPv6 address as one number
- UUIDs, which are 128 bits
- The full product of two 64-bit numbers
Need negative numbers? The signed type of the same width is int128, from −170,141,183,460,469,231,731,687,303,715,884,105,728 to 170,141,183,460,469,231,731,687,303,715,884,105,727.
Every integer type
| Type | Minimum | Maximum |
|---|---|---|
| int8 | −128 | 127 |
| uint8 | 0 | 255 |
| int16 | −32, |
32, |
| uint16 | 0 | 65, |
| int32 | −2, |
2, |
| uint32 | 0 | 4, |
| int64 | −9, |
9, |
| uint64 | 0 | 18, |
| int128 | −170, |
170, |
| uint128 this page | 0 | 340, |
Questions
What is the maximum value of uint128?
340,
Why does uint128 start at 0?
An unsigned type spends all 128 bits on magnitude and none on a sign, so it cannot hold negative numbers but reaches twice as far: 340,
How many values can uint128 hold?
2¹²⁸ = 340,
What happens when uint128 overflows?
On the hardware the result keeps only its low 128 bits, so 340,
What is uint128 called in other languages?
C and C++: unsigned __int128; C#: UInt128; Rust: u128; Swift: UInt128. No common SQL database has it as a column type.