CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scala-native--nativelib-native0-5-3

Native interoperability library for Scala Native providing unsafe operations, C-style data types, and memory management primitives for direct interaction with native code

Pending
Overview
Eval results
Files

unsigned-types.mddocs/

Unsigned Types

Scala Native provides full-featured unsigned integer types with proper arithmetic, bitwise operations, and conversions for systems programming and C interoperability.

Unsigned Integer Types

Core Unsigned Types

final class UByte extends AnyVal {
  // Arithmetic operations
  def +(other: UByte): UByte
  def -(other: UByte): UByte  
  def *(other: UByte): UByte
  def /(other: UByte): UByte
  def %(other: UByte): UByte
  def unary_-: UByte
  
  // Bitwise operations
  def &(other: UByte): UByte
  def |(other: UByte): UByte
  def ^(other: UByte): UByte
  def unary_~: UByte
  def <<(shift: Int): UByte
  def >>(shift: Int): UByte
  def >>>(shift: Int): UByte
  
  // Comparison operations
  def ==(other: UByte): Boolean
  def !=(other: UByte): Boolean
  def <(other: UByte): Boolean
  def <=(other: UByte): Boolean
  def >(other: UByte): Boolean
  def >=(other: UByte): Boolean
  
  // Conversions
  def toByte: Byte
  def toShort: Short
  def toInt: Int
  def toLong: Long
  def toFloat: Float
  def toDouble: Double
  def toUShort: UShort
  def toUInt: UInt
  def toULong: ULong
  def toUSize: USize
  def toCSize: CSize
}

final class UShort extends AnyVal {
  // Same operations as UByte with UShort types
  def +(other: UShort): UShort
  def -(other: UShort): UShort
  def *(other: UShort): UShort
  def /(other: UShort): UShort
  def %(other: UShort): UShort
  def unary_-: UShort
  
  def &(other: UShort): UShort
  def |(other: UShort): UShort
  def ^(other: UShort): UShort
  def unary_~: UShort
  def <<(shift: Int): UShort
  def >>(shift: Int): UShort
  def >>>(shift: Int): UShort
  
  def ==(other: UShort): Boolean
  def !=(other: UShort): Boolean
  def <(other: UShort): Boolean
  def <=(other: UShort): Boolean
  def >(other: UShort): Boolean
  def >=(other: UShort): Boolean
  
  def toByte: Byte
  def toShort: Short
  def toInt: Int  
  def toLong: Long
  def toFloat: Float
  def toDouble: Double
  def toUByte: UByte
  def toUInt: UInt
  def toULong: ULong
  def toUSize: USize
  def toCSize: CSize
}

final class UInt extends AnyVal {
  // Same pattern as UByte/UShort with UInt types
  def +(other: UInt): UInt
  def -(other: UInt): UInt
  def *(other: UInt): UInt
  def /(other: UInt): UInt
  def %(other: UInt): UInt
  def unary_-: UInt
  
  def &(other: UInt): UInt
  def |(other: UInt): UInt
  def ^(other: UInt): UInt
  def unary_~: UInt
  def <<(shift: Int): UInt
  def >>(shift: Int): UInt
  def >>>(shift: Int): UInt
  
  def ==(other: UInt): Boolean
  def !=(other: UInt): Boolean
  def <(other: UInt): Boolean
  def <=(other: UInt): Boolean
  def >(other: UInt): Boolean
  def >=(other: UInt): Boolean
  
  def toByte: Byte
  def toShort: Short
  def toInt: Int
  def toLong: Long
  def toFloat: Float
  def toDouble: Double
  def toUByte: UByte
  def toUShort: UShort
  def toULong: ULong
  def toUSize: USize
  def toCSize: CSize
}

final class ULong extends AnyVal {
  // Same pattern with ULong types
  def +(other: ULong): ULong
  def -(other: ULong): ULong
  def *(other: ULong): ULong
  def /(other: ULong): ULong
  def %(other: ULong): ULong
  def unary_-: ULong
  
  def &(other: ULong): ULong
  def |(other: ULong): ULong
  def ^(other: ULong): ULong
  def unary_~: ULong
  def <<(shift: Int): ULong
  def >>(shift: Int): ULong
  def >>>(shift: Int): ULong
  
  def ==(other: ULong): Boolean
  def !=(other: ULong): Boolean
  def <(other: ULong): Boolean
  def <=(other: ULong): Boolean
  def >(other: ULong): Boolean
  def >=(other: ULong): Boolean
  
  def toByte: Byte
  def toShort: Short
  def toInt: Int
  def toLong: Long
  def toFloat: Float
  def toDouble: Double
  def toUByte: UByte
  def toUShort: UShort
  def toUInt: UInt
  def toUSize: USize
  def toCSize: CSize
}

final class USize extends AnyVal {
  // Platform-dependent: UInt on 32-bit, ULong on 64-bit
  def +(other: USize): USize
  def -(other: USize): USize
  def *(other: USize): USize
  def /(other: USize): USize
  def %(other: USize): USize
  def unary_-: USize
  
  def &(other: USize): USize
  def |(other: USize): USize
  def ^(other: USize): USize
  def unary_~: USize
  def <<(shift: Int): USize
  def >>(shift: Int): USize
  def >>>(shift: Int): USize
  
  def ==(other: USize): Boolean
  def !=(other: USize): Boolean
  def <(other: USize): Boolean
  def <=(other: USize): Boolean
  def >(other: USize): Boolean
  def >=(other: USize): Boolean
  
  def toByte: Byte
  def toShort: Short
  def toInt: Int
  def toLong: Long
  def toFloat: Float
  def toDouble: Double
  def toSize: Size
  def toUByte: UByte
  def toUShort: UShort
  def toUInt: UInt
  def toULong: ULong
  def toCSize: CSize
}

Companion Objects

Each unsigned type has a companion object with constants and utilities:

object UByte {
  def valueOf(value: Byte): UByte
  final val MaxValue: UByte  // 255
  final val MinValue: UByte  // 0
}

object UShort {
  def valueOf(value: Short): UShort
  final val MaxValue: UShort  // 65535
  final val MinValue: UShort  // 0
}

object UInt {
  def valueOf(value: Int): UInt
  final val MaxValue: UInt  // 4294967295
  final val MinValue: UInt  // 0
}

object ULong {
  def valueOf(value: Long): ULong
  final val MaxValue: ULong  // 18446744073709551615
  final val MinValue: ULong  // 0
}

object USize {
  def valueOf(value: Size): USize
  final val MaxValue: USize  // Platform dependent
  final val MinValue: USize  // 0
}

Rich Extension Methods

For Signed Types

Implicit extension methods to convert signed types to unsigned:

implicit class UnsignedRichByte(val value: Byte) extends AnyVal {
  def toUByte: UByte
  def toUShort: UShort  
  def toUInt: UInt
  def toULong: ULong
  def toCSize: CSize
}

implicit class UnsignedRichShort(val value: Short) extends AnyVal {
  def toUByte: UByte
  def toUShort: UShort
  def toUInt: UInt
  def toULong: ULong
  def toCSize: CSize
}

implicit class UnsignedRichInt(val value: Int) extends AnyVal {
  def toUByte: UByte
  def toUShort: UShort
  def toUInt: UInt
  def toULong: ULong
  def toUSize: USize
  def toCSize: CSize
}

implicit class UnsignedRichLong(val value: Long) extends AnyVal {
  def toUByte: UByte
  def toUShort: UShort
  def toUInt: UInt
  def toULong: ULong
  def toUSize: USize
  def toCSize: CSize
}

Usage Examples

Basic Arithmetic

import scala.scalanative.unsigned._

val a: UInt = 42.toUInt
val b: UInt = 24.toUInt

val sum: UInt = a + b        // 66
val diff: UInt = a - b       // 18
val product: UInt = a * b    // 1008
val quotient: UInt = a / b   // 1
val remainder: UInt = a % b  // 18

// Overflow behavior (wraps around)
val max: UInt = UInt.MaxValue  // 4294967295
val overflow: UInt = max + 1.toUInt  // 0 (wraps to minimum)

Bitwise Operations

import scala.scalanative.unsigned._

val x: UInt = 0xFF.toUInt    // 255
val y: UInt = 0x0F.toUInt    // 15

val and: UInt = x & y        // 15 (0x0F)
val or: UInt = x | y         // 255 (0xFF)
val xor: UInt = x ^ y        // 240 (0xF0)
val not: UInt = ~x           // 4294967040 (0xFFFFFF00)

// Bit shifting
val shifted: UInt = x << 4   // 4080 (0xFF0)
val rightShift: UInt = x >> 4        // 15 (0x0F)
val logicalShift: UInt = x >>> 4     // 15 (0x0F)

Comparisons

import scala.scalanative.unsigned._

val a: UInt = 100.toUInt
val b: UInt = 200.toUInt

val equal: Boolean = a == b      // false
val notEqual: Boolean = a != b   // true
val less: Boolean = a < b        // true
val lessEqual: Boolean = a <= b  // true
val greater: Boolean = a > b     // false
val greaterEqual: Boolean = a >= b  // false

// Comparison with maximum values
val maxByte: UByte = UByte.MaxValue
val normalByte: UByte = 100.toByte.toUByte
val isLess: Boolean = normalByte < maxByte  // true

Type Conversions

import scala.scalanative.unsigned._

// From signed to unsigned
val signedInt: Int = -1
val unsignedInt: UInt = signedInt.toUInt  // 4294967295 (bit pattern preserved)

// Between unsigned types
val byte: UByte = 255.toByte.toUByte
val short: UShort = byte.toUShort    // 255
val int: UInt = short.toUInt         // 255
val long: ULong = int.toULong        // 255

// Back to signed (with potential overflow)
val backToSigned: Int = int.toInt    // 255
val overflowCase: Int = UInt.MaxValue.toInt  // -1 (overflow)

Platform-dependent USize

import scala.scalanative.unsigned._

val size: USize = 1024.toUSize
val doubled: USize = size * 2.toUSize

// USize matches pointer size (32-bit or 64-bit)
val asPointer: Ptr[Byte] = size.toLong.toPtr[Byte]

// For C size_t compatibility
val csize: CSize = size.toCSize

Working with C Types

import scala.scalanative.unsafe._
import scala.scalanative.unsigned._

// Using unsigned types with C functions
Zone.acquire { implicit z =>
  val count: CSize = 10.toUSize  // Equivalent to C size_t
  val buffer: Ptr[UInt] = alloc[UInt](count.toInt)
  
  // Initialize with unsigned values
  var i: UInt = 0.toUInt
  while (i < 10.toUInt) {
    buffer(i.toInt) = i * i  // Store squares
    i = i + 1.toUInt
  }
  
  // Read back values
  val value: UInt = buffer(5)  // Get 5th element (25)
}

Error Handling and Edge Cases

import scala.scalanative.unsigned._

// Division by zero throws ArithmeticException
val zero: UInt = 0.toUInt
try {
  val result: UInt = 42.toUInt / zero
} catch {
  case _: ArithmeticException => println("Division by zero")
}

// Large number handling
val large: ULong = Long.MaxValue.toULong
val doubled: ULong = large + large  // Overflow wrapping

// Precision loss in conversions
val precise: ULong = ULong.MaxValue
val imprecise: Double = precise.toDouble  // May lose precision
val recovered: ULong = imprecise.toLong.toULong  // May not equal original

Best Practices

  1. Use appropriate types: Choose the smallest unsigned type that fits your data range
  2. Be aware of overflow: Unsigned arithmetic wraps around on overflow
  3. Handle conversions carefully: Converting between signed/unsigned can change values
  4. Use with C interop: Unsigned types map directly to C unsigned types
  5. Check for division by zero: Unlike some languages, Scala throws exceptions
  6. Consider precision: Large unsigned values may lose precision when converted to floating point
  7. Use extension methods: .toUInt style conversions are more readable than constructors

Install with Tessl CLI

npx tessl i tessl/maven-org-scala-native--nativelib-native0-5-3

docs

annotations.md

arrays-runtime.md

c-interop.md

index.md

memory-management.md

unsigned-types.md

tile.json