#Unsigned Integer Types
Last modified: 07 February 2025
In addition to integer types, Kotlin provides the following types for unsigned integer numbers:
| Type | Size (bits) | Min value | Max value |
|---|---|---|---|
| UByte | 8 | 0 | 255 |
| UShort | 16 | 0 | 65,535 |
| UInt | 32 | 0 | 4,294,967,295 ($2^{32} - 1$) |
| ULong | 64 | 0 | 18,446,744,073,709,551,615 ($2^{64} - 1$) |
Unsigned types support most of the operations of their signed counterparts.
Unsigned numbers are implemented as inline classes with a single storage property that contains the corresponding signed counterpart type of the same width. If you want to convert between unsigned and signed integer types, make sure you update your code so that any function calls and operations support the new type.
#Unsigned Arrays and Ranges
Note: Unsigned arrays and operations on them are in Beta. They can be changed incompatibly at any time. Opt-in is required.
Same as for primitives, each unsigned type has a corresponding type that represents arrays of that type:
- UByteArray: An array of unsigned bytes.
- UShortArray: An array of unsigned shorts.
- UIntArray: An array of unsigned ints.
- ULongArray: An array of unsigned longs.
Like signed integer arrays, these provide a similar API to the Array class without boxing overhead.
To use them without warnings, opt-in with the @ExperimentalUnsignedTypes annotation. While the arrays are in Beta, ranges and progressions (supported via UIntRange, UIntProgression, ULongRange, and ULongProgression) are considered stable.
#Unsigned Integer Literals
To make unsigned integers easier to use, you can append a suffix to an integer literal:
- u and U signify unsigned literals. If no expected type is provided, the compiler chooses
UIntorULongbased on the size:
kotlinval b: UByte = 1u // UByte, expected type provided
val s: UShort = 1u // UShort, expected type provided
val l: ULong = 1u // ULong, expected type provided
val a1 = 42u // UInt: fits in UInt
val a2 = 0xFFFF_FFFF_FFFFu // ULong: doesn't fit in UInt
- uL and UL explicitly specify an unsigned long:
kotlin val a = 1UL // ULong, even though it fits into UInt
#Use Cases
The main use case is utilizing the full bit range of an integer to represent positive values.
- Hexadecimal Constants: Representing values like 32-bit ARGB colors that exceed signed limits.
` kotlin data class Color(val representation: UInt)
val yellow = Color(0xFFCC00CCu)
- Byte Array Initialization: Initializing without explicit
toByte()casts.
kotlin val byteOrderMarkUtf8 = ubyteArrayOf(0xEFu, 0xBBu, 0xBFu)
- Native Interoperability: Mapping to native APIs that use unsigned types in their signatures.
#Non-goals
Unsigned integers are not intended to be used merely to restrict a domain to non-negative numbers (like collection sizes or indices).
- Error Detection: Signed integers help detect accidental overflows or signal errors (e.g.,
List.lastIndexbeing-1). - Type Hierarchy: Unsigned integers are not a subset or subtype of signed integers; they represent a different range entirely.