Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

ULong is an unsigned 64-bit integer type in Kotlin that represents values from 0 to 18,446,744,073,709,551,615 (26412^{64} - 1). It is implemented as a value class (specifically, a @JvmInline value class) that wraps a standard signed 64-bit Long. This design provides unsigned arithmetic and bitwise semantics while avoiding object allocation overhead at runtime, compiling down to a primitive long on the JVM in unboxed contexts.

Instantiation and Syntax

ULong literals are defined by appending the u (or U) and L suffixes to an integer literal.
val explicitULong: ULong = 18446744073709551615uL
val inferredULong = 123UL // Type inferred as ULong
val hexULong = 0xFFFFFFFFFFFFFFFFuL
val binULong = 0b10101010uL
Standard numeric types and strings can be explicitly converted to ULong using extension functions:
val fromInt: ULong = 42.toULong()
val fromSignedLong: ULong = (-1L).toULong() // Results in ULong.MAX_VALUE due to two's complement
val fromString: ULong = "18446744073709551615".toULong()

Memory Representation and Boxing

Because ULong is an inline value class, the Kotlin compiler treats it as a primitive long during execution whenever possible. However, boxing occurs when ULong is used in generic contexts, nullable types, or as an interface implementation.
// Unboxed: Stored as a primitive 64-bit integer (long) on the JVM
val unboxed: ULong = 100UL 

// Boxed: Instantiates a wrapper object on the heap
val boxed: ULong? = 100UL 
val genericList: List<ULong> = listOf(100UL) 

Operations and Semantics

ULong supports standard arithmetic (+, -, *, /, %) and comparison (<, >, ==) operators. The Kotlin compiler translates these into unsigned operations at the bytecode level (e.g., utilizing java.lang.Long.divideUnsigned on the JVM).
val a = 10UL
val b = 3UL
val division = a / b // Evaluates to 3UL
Bitwise Operations: ULong supports standard bitwise operations (and, or, xor, inv). However, bitwise shift semantics differ from signed Long:
  • shr (Shift Right): Performs a logical shift (zero-fill), whereas shr on a signed Long performs an arithmetic shift (sign-extend).
  • ushr (Unsigned Shift Right): Not available on ULong, as shr already provides the logical shift behavior.
  • shl (Shift Left): Functions identically to signed integers.
val value = 0xFFFFFFFFFFFFFFFFuL
val shifted = value shr 8 // Fills highest 8 bits with 0s

ULongArray

To prevent boxing overhead when working with collections of ULong data, Kotlin provides ULongArray. At the JVM level, ULongArray is backed by a primitive long[], ensuring contiguous memory allocation and zero boxing per element.
// Initialization via factory function
val array = ULongArray(5) { index -> (index * 2).toULong() }

// Initialization via vararg function
val literalArray = ulongArrayOf(1UL, 2UL, 3UL)

// Access and mutation
array[0] = 99UL
val firstElement = array[0]

Type Constraints and Interoperability

  • Widening Conversions: Kotlin does not implicitly widen types. A UInt cannot be passed to a function expecting a ULong without an explicit .toULong() cast.
  • Java Interoperability: Because Java lacks native unsigned types, ULong is exposed to Java code as a signed long. Functions accepting ULong in Kotlin will undergo name mangling in the generated JVM bytecode to prevent signature collisions with functions accepting signed Long.
Master Kotlin with Deep Grasping Methodology!Learn More