uint64: the 64-bit unsigned integer
uint64 holds every whole number from 0 to 18,
uint64 limits
- Maximum
- 18,
446, 744, 073, 709, 551, 615 power2⁶⁴ − 1hex0xFFFFFFFFFFFFFFFFbinary1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 - Minimum
- 0power0hex0x0000000000000000binary0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
- Distinct values
- 2⁶⁴ = 18,
446, 744, 073, 709, 551, 616 - Size
- 64 bits, 8 bytes
uint64 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: 18,
446, 744, 073, 709, 551, 616. - That is above the maximum of uint64, 18,
446, 744, 073, 709, 551, 615. - The hardware keeps only the low 64 bits, which is the same as taking the answer modulo 2⁶⁴ = 18,
446, 744, 073, 709, 551, 616: 0.
What uint64 is called in each language
| Language | Type | Limits in code | Note |
|---|---|---|---|
| C and C++ | uint64_t | UINT64_MAX | size_t is 64 bits on 64-bit platforms. |
| Java | none | Use long with Long.toUnsignedString, Long.compareUnsigned and friends. | |
| C# | ulong | ulong.MaxValue | |
| Rust | u64 | u64::MAX | usize is the pointer width: 64 bits on 64-bit targets. |
| Go | uint64 | math.MaxUint64 | uint is 32 or 64 bits, depending on the platform. |
| Swift | UInt64 | UInt64.max | |
| Kotlin | ULong | ULong.MAX_VALUE | |
| MySQL | BIGINT UNSIGNED | ||
| PostgreSQL | none | PostgreSQL has no unsigned integer types; numeric holds the whole range. | |
| SQL Server | none | SQL Server has no unsigned types apart from tinyint. | |
| JavaScript | BigUint64Array element | BigInt.asUintN(64, x) wraps a BigInt into 64 bits. | |
| Python | ctypes.c_uint64 |
Only names with exactly 64 bits on every platform are listed as the type. Types whose width depends on the platform, such as C’s long, Go’s int and Rust’s isize, are in the notes.
What happens when uint64 overflows
In 64 bits, 18,
BigInt.asUintN(64, 18446744073709551615n + 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 uint64
- Counting down to zero with an unsigned counter. A loop such as for (i = n; i >= 0; i--) never ends when i is uint64: i >= 0 is always true, and 0 − 1 wraps to 18,
446, 744, 073, 709, 551, 615. Test i > 0 and use i − 1 inside, or use a signed counter. - Comparing signed with unsigned in C. -1 < x is false when x is a uint64_t, even when x is 0: the −1 is converted to uint64 first and becomes 18,
446, 744, 073, 709, 551, 615. - Finding a midpoint as (low + high) / 2. When low and high are both 9,
223, 372, 036, 854, 775, 808 or more, just over half the maximum, their sum overflows uint64. low + (high − low) / 2 gives the same midpoint without the overflow. - Sending 64-bit IDs through JSON to JavaScript. JSON.parse turns every number into a double, which is exact only up to 2⁵³ − 1. An ID of 9,
007, 199, 254, 740, 993 arrives as 9, 007, 199, 254, 740, 992. Send large IDs as strings.
Where you meet uint64
- size_t and memory addresses on 64-bit platforms
- Hashes such as 64-bit FNV
- File sizes and offsets
- 64-bit IDs such as Discord snowflakes, which APIs send as strings so JavaScript does not round them
Need negative numbers? The signed type of the same width is int64, from −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.
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 this page | 0 | 18, |
| int128 | −170, |
170, |
| uint128 | 0 | 340, |
Questions
What is the maximum value of uint64?
18,
Why does uint64 start at 0?
An unsigned type spends all 64 bits on magnitude and none on a sign, so it cannot hold negative numbers but reaches twice as far: 18,
How many values can uint64 hold?
2⁶⁴ = 18,
What happens when uint64 overflows?
On the hardware the result keeps only its low 64 bits, so 18,
What is uint64 called in other languages?
C and C++: uint64_t; C#: ulong; Rust: u64; Go: uint64; Swift: UInt64; Kotlin: ULong; Python: ctypes.c_uint64. In SQL: BIGINT UNSIGNED in MySQL.