uint16: the 16-bit unsigned integer
uint16 holds every whole number from 0 to 65,535, which is 0 to 2¹⁶ − 1. That is 2¹⁶ = 65,536 values in 16 bits, none of them negative.
uint16 limits
- Maximum
- 65,535power2¹⁶ − 1hex0xFFFFbinary1111 1111 1111 1111
- Minimum
- 0power0hex0x0000binary0000 0000 0000 0000
- Distinct values
- 2¹⁶ = 65,536
- Size
- 16 bits, 2 bytes
uint16 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: 65,536.
- That is above the maximum of uint16, 65,535.
- The hardware keeps only the low 16 bits, which is the same as taking the answer modulo 2¹⁶ = 65,536: 0.
What uint16 is called in each language
| Language | Type | Limits in code | Note |
|---|---|---|---|
| C and C++ | uint16_t | UINT16_MAX | |
| Java | char | Character.MAX_VALUE | char is an unsigned 16-bit UTF-16 code unit, and does arithmetic. |
| C# | ushort | ushort.MaxValue | |
| Rust | u16 | u16::MAX | |
| Go | uint16 | math.MaxUint16 | |
| Swift | UInt16 | UInt16.max | |
| Kotlin | UShort | UShort.MAX_VALUE | |
| MySQL | SMALLINT UNSIGNED | ||
| PostgreSQL | none | PostgreSQL has no unsigned integer types. | |
| SQL Server | none | SQL Server has no unsigned types apart from tinyint. | |
| JavaScript | Uint16Array element | ||
| Python | ctypes.c_uint16 |
Only names with exactly 16 bits on every platform are listed as the type.
What happens when uint16 overflows
In 16 bits, 65,535 + 1 wraps to 0, and 0 − 1 wraps to 65,535. The processor keeps the low 16 bits of the answer, which is the same as working modulo 2¹⁶. You can see it in JavaScript:
new Uint16Array([65535 + 1])[0] → 0
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 |
In C and C++, arithmetic on 16-bit types is done in int, so the sum itself does not overflow; it wraps when stored back into the uint16_t. For unsigned types that conversion is always defined: it wraps. The promotion has a catch: it is to signed int, so uint16_t × uint16_t is a signed multiplication, and 65,535 × 65,535 overflows it.
Common mistakes with uint16
- Counting down to zero with an unsigned counter. A loop such as for (i = n; i >= 0; i--) never ends when i is uint16: i >= 0 is always true, and 0 − 1 wraps to 65,535. Test i > 0 and use i − 1 inside, or use a signed counter.
- Multiplying two uint16_t values in C. Both are promoted to signed int first, so 65,535 × 65,535 = 4,294,836,225 overflows a 32-bit int (maximum 2,147,483,647), which is undefined behaviour. Cast one operand to uint32_t before multiplying.
Where you meet uint16
- TCP and UDP port numbers, 0 to 65,535
- UTF-16 code units
- Unicode code points in the Basic Multilingual Plane
Need negative numbers? The signed type of the same width is int16, from −32,768 to 32,767.
Every integer type
| Type | Minimum | Maximum |
|---|---|---|
| int8 | −128 | 127 |
| uint8 | 0 | 255 |
| int16 | −32, |
32, |
| uint16 this page | 0 | 65, |
| int32 | −2, |
2, |
| uint32 | 0 | 4, |
| int64 | −9, |
9, |
| uint64 | 0 | 18, |
| int128 | −170, |
170, |
| uint128 | 0 | 340, |
Questions
What is the maximum value of uint16?
65,535, which is 2¹⁶ − 1 or 0xFFFF in hex. The minimum is 0.
Why does uint16 start at 0?
An unsigned type spends all 16 bits on magnitude and none on a sign, so it cannot hold negative numbers but reaches twice as far: 65,535 instead of the 32,767 of int16. Subtracting 1 from 0 wraps to the maximum.
How many values can uint16 hold?
2¹⁶ = 65,536 distinct values, from 0 to 65,535.
What happens when uint16 overflows?
On the hardware the result keeps only its low 16 bits, so 65,535 + 1 becomes 0. In C, C++, Java, C# and Kotlin, arithmetic on 16-bit values is done in int (UInt in Kotlin), so 65,535 + 1 is 65,536 as an int; it becomes 0 only when stored back into the 16-bit type, as x++, a cast or (except in Kotlin, where it does not compile) x += 1 do. Go wraps at 16 bits directly, Rust panics in debug builds and wraps in release builds, and Swift stops with a runtime error.
What is uint16 called in other languages?
C and C++: uint16_t; Java: char; C#: ushort; Rust: u16; Go: uint16; Swift: UInt16; Kotlin: UShort; Python: ctypes.c_uint16. In SQL: SMALLINT UNSIGNED in MySQL.