or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdarrays-runtime.mdc-interop.mdindex.mdmemory-management.mdunsigned-types.md

unsigned-types.mddocs/

0

# Unsigned Types

1

2

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

3

4

## Unsigned Integer Types

5

6

### Core Unsigned Types

7

8

```scala { .api }

9

final class UByte extends AnyVal {

10

// Arithmetic operations

11

def +(other: UByte): UByte

12

def -(other: UByte): UByte

13

def *(other: UByte): UByte

14

def /(other: UByte): UByte

15

def %(other: UByte): UByte

16

def unary_-: UByte

17

18

// Bitwise operations

19

def &(other: UByte): UByte

20

def |(other: UByte): UByte

21

def ^(other: UByte): UByte

22

def unary_~: UByte

23

def <<(shift: Int): UByte

24

def >>(shift: Int): UByte

25

def >>>(shift: Int): UByte

26

27

// Comparison operations

28

def ==(other: UByte): Boolean

29

def !=(other: UByte): Boolean

30

def <(other: UByte): Boolean

31

def <=(other: UByte): Boolean

32

def >(other: UByte): Boolean

33

def >=(other: UByte): Boolean

34

35

// Conversions

36

def toByte: Byte

37

def toShort: Short

38

def toInt: Int

39

def toLong: Long

40

def toFloat: Float

41

def toDouble: Double

42

def toUShort: UShort

43

def toUInt: UInt

44

def toULong: ULong

45

def toUSize: USize

46

def toCSize: CSize

47

}

48

49

final class UShort extends AnyVal {

50

// Same operations as UByte with UShort types

51

def +(other: UShort): UShort

52

def -(other: UShort): UShort

53

def *(other: UShort): UShort

54

def /(other: UShort): UShort

55

def %(other: UShort): UShort

56

def unary_-: UShort

57

58

def &(other: UShort): UShort

59

def |(other: UShort): UShort

60

def ^(other: UShort): UShort

61

def unary_~: UShort

62

def <<(shift: Int): UShort

63

def >>(shift: Int): UShort

64

def >>>(shift: Int): UShort

65

66

def ==(other: UShort): Boolean

67

def !=(other: UShort): Boolean

68

def <(other: UShort): Boolean

69

def <=(other: UShort): Boolean

70

def >(other: UShort): Boolean

71

def >=(other: UShort): Boolean

72

73

def toByte: Byte

74

def toShort: Short

75

def toInt: Int

76

def toLong: Long

77

def toFloat: Float

78

def toDouble: Double

79

def toUByte: UByte

80

def toUInt: UInt

81

def toULong: ULong

82

def toUSize: USize

83

def toCSize: CSize

84

}

85

86

final class UInt extends AnyVal {

87

// Same pattern as UByte/UShort with UInt types

88

def +(other: UInt): UInt

89

def -(other: UInt): UInt

90

def *(other: UInt): UInt

91

def /(other: UInt): UInt

92

def %(other: UInt): UInt

93

def unary_-: UInt

94

95

def &(other: UInt): UInt

96

def |(other: UInt): UInt

97

def ^(other: UInt): UInt

98

def unary_~: UInt

99

def <<(shift: Int): UInt

100

def >>(shift: Int): UInt

101

def >>>(shift: Int): UInt

102

103

def ==(other: UInt): Boolean

104

def !=(other: UInt): Boolean

105

def <(other: UInt): Boolean

106

def <=(other: UInt): Boolean

107

def >(other: UInt): Boolean

108

def >=(other: UInt): Boolean

109

110

def toByte: Byte

111

def toShort: Short

112

def toInt: Int

113

def toLong: Long

114

def toFloat: Float

115

def toDouble: Double

116

def toUByte: UByte

117

def toUShort: UShort

118

def toULong: ULong

119

def toUSize: USize

120

def toCSize: CSize

121

}

122

123

final class ULong extends AnyVal {

124

// Same pattern with ULong types

125

def +(other: ULong): ULong

126

def -(other: ULong): ULong

127

def *(other: ULong): ULong

128

def /(other: ULong): ULong

129

def %(other: ULong): ULong

130

def unary_-: ULong

131

132

def &(other: ULong): ULong

133

def |(other: ULong): ULong

134

def ^(other: ULong): ULong

135

def unary_~: ULong

136

def <<(shift: Int): ULong

137

def >>(shift: Int): ULong

138

def >>>(shift: Int): ULong

139

140

def ==(other: ULong): Boolean

141

def !=(other: ULong): Boolean

142

def <(other: ULong): Boolean

143

def <=(other: ULong): Boolean

144

def >(other: ULong): Boolean

145

def >=(other: ULong): Boolean

146

147

def toByte: Byte

148

def toShort: Short

149

def toInt: Int

150

def toLong: Long

151

def toFloat: Float

152

def toDouble: Double

153

def toUByte: UByte

154

def toUShort: UShort

155

def toUInt: UInt

156

def toUSize: USize

157

def toCSize: CSize

158

}

159

160

final class USize extends AnyVal {

161

// Platform-dependent: UInt on 32-bit, ULong on 64-bit

162

def +(other: USize): USize

163

def -(other: USize): USize

164

def *(other: USize): USize

165

def /(other: USize): USize

166

def %(other: USize): USize

167

def unary_-: USize

168

169

def &(other: USize): USize

170

def |(other: USize): USize

171

def ^(other: USize): USize

172

def unary_~: USize

173

def <<(shift: Int): USize

174

def >>(shift: Int): USize

175

def >>>(shift: Int): USize

176

177

def ==(other: USize): Boolean

178

def !=(other: USize): Boolean

179

def <(other: USize): Boolean

180

def <=(other: USize): Boolean

181

def >(other: USize): Boolean

182

def >=(other: USize): Boolean

183

184

def toByte: Byte

185

def toShort: Short

186

def toInt: Int

187

def toLong: Long

188

def toFloat: Float

189

def toDouble: Double

190

def toSize: Size

191

def toUByte: UByte

192

def toUShort: UShort

193

def toUInt: UInt

194

def toULong: ULong

195

def toCSize: CSize

196

}

197

```

198

199

### Companion Objects

200

201

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

202

203

```scala { .api }

204

object UByte {

205

def valueOf(value: Byte): UByte

206

final val MaxValue: UByte // 255

207

final val MinValue: UByte // 0

208

}

209

210

object UShort {

211

def valueOf(value: Short): UShort

212

final val MaxValue: UShort // 65535

213

final val MinValue: UShort // 0

214

}

215

216

object UInt {

217

def valueOf(value: Int): UInt

218

final val MaxValue: UInt // 4294967295

219

final val MinValue: UInt // 0

220

}

221

222

object ULong {

223

def valueOf(value: Long): ULong

224

final val MaxValue: ULong // 18446744073709551615

225

final val MinValue: ULong // 0

226

}

227

228

object USize {

229

def valueOf(value: Size): USize

230

final val MaxValue: USize // Platform dependent

231

final val MinValue: USize // 0

232

}

233

```

234

235

## Rich Extension Methods

236

237

### For Signed Types

238

239

Implicit extension methods to convert signed types to unsigned:

240

241

```scala { .api }

242

implicit class UnsignedRichByte(val value: Byte) extends AnyVal {

243

def toUByte: UByte

244

def toUShort: UShort

245

def toUInt: UInt

246

def toULong: ULong

247

def toCSize: CSize

248

}

249

250

implicit class UnsignedRichShort(val value: Short) extends AnyVal {

251

def toUByte: UByte

252

def toUShort: UShort

253

def toUInt: UInt

254

def toULong: ULong

255

def toCSize: CSize

256

}

257

258

implicit class UnsignedRichInt(val value: Int) extends AnyVal {

259

def toUByte: UByte

260

def toUShort: UShort

261

def toUInt: UInt

262

def toULong: ULong

263

def toUSize: USize

264

def toCSize: CSize

265

}

266

267

implicit class UnsignedRichLong(val value: Long) extends AnyVal {

268

def toUByte: UByte

269

def toUShort: UShort

270

def toUInt: UInt

271

def toULong: ULong

272

def toUSize: USize

273

def toCSize: CSize

274

}

275

```

276

277

## Usage Examples

278

279

### Basic Arithmetic

280

281

```scala

282

import scala.scalanative.unsigned._

283

284

val a: UInt = 42.toUInt

285

val b: UInt = 24.toUInt

286

287

val sum: UInt = a + b // 66

288

val diff: UInt = a - b // 18

289

val product: UInt = a * b // 1008

290

val quotient: UInt = a / b // 1

291

val remainder: UInt = a % b // 18

292

293

// Overflow behavior (wraps around)

294

val max: UInt = UInt.MaxValue // 4294967295

295

val overflow: UInt = max + 1.toUInt // 0 (wraps to minimum)

296

```

297

298

### Bitwise Operations

299

300

```scala

301

import scala.scalanative.unsigned._

302

303

val x: UInt = 0xFF.toUInt // 255

304

val y: UInt = 0x0F.toUInt // 15

305

306

val and: UInt = x & y // 15 (0x0F)

307

val or: UInt = x | y // 255 (0xFF)

308

val xor: UInt = x ^ y // 240 (0xF0)

309

val not: UInt = ~x // 4294967040 (0xFFFFFF00)

310

311

// Bit shifting

312

val shifted: UInt = x << 4 // 4080 (0xFF0)

313

val rightShift: UInt = x >> 4 // 15 (0x0F)

314

val logicalShift: UInt = x >>> 4 // 15 (0x0F)

315

```

316

317

### Comparisons

318

319

```scala

320

import scala.scalanative.unsigned._

321

322

val a: UInt = 100.toUInt

323

val b: UInt = 200.toUInt

324

325

val equal: Boolean = a == b // false

326

val notEqual: Boolean = a != b // true

327

val less: Boolean = a < b // true

328

val lessEqual: Boolean = a <= b // true

329

val greater: Boolean = a > b // false

330

val greaterEqual: Boolean = a >= b // false

331

332

// Comparison with maximum values

333

val maxByte: UByte = UByte.MaxValue

334

val normalByte: UByte = 100.toByte.toUByte

335

val isLess: Boolean = normalByte < maxByte // true

336

```

337

338

### Type Conversions

339

340

```scala

341

import scala.scalanative.unsigned._

342

343

// From signed to unsigned

344

val signedInt: Int = -1

345

val unsignedInt: UInt = signedInt.toUInt // 4294967295 (bit pattern preserved)

346

347

// Between unsigned types

348

val byte: UByte = 255.toByte.toUByte

349

val short: UShort = byte.toUShort // 255

350

val int: UInt = short.toUInt // 255

351

val long: ULong = int.toULong // 255

352

353

// Back to signed (with potential overflow)

354

val backToSigned: Int = int.toInt // 255

355

val overflowCase: Int = UInt.MaxValue.toInt // -1 (overflow)

356

```

357

358

### Platform-dependent USize

359

360

```scala

361

import scala.scalanative.unsigned._

362

363

val size: USize = 1024.toUSize

364

val doubled: USize = size * 2.toUSize

365

366

// USize matches pointer size (32-bit or 64-bit)

367

val asPointer: Ptr[Byte] = size.toLong.toPtr[Byte]

368

369

// For C size_t compatibility

370

val csize: CSize = size.toCSize

371

```

372

373

### Working with C Types

374

375

```scala

376

import scala.scalanative.unsafe._

377

import scala.scalanative.unsigned._

378

379

// Using unsigned types with C functions

380

Zone.acquire { implicit z =>

381

val count: CSize = 10.toUSize // Equivalent to C size_t

382

val buffer: Ptr[UInt] = alloc[UInt](count.toInt)

383

384

// Initialize with unsigned values

385

var i: UInt = 0.toUInt

386

while (i < 10.toUInt) {

387

buffer(i.toInt) = i * i // Store squares

388

i = i + 1.toUInt

389

}

390

391

// Read back values

392

val value: UInt = buffer(5) // Get 5th element (25)

393

}

394

```

395

396

### Error Handling and Edge Cases

397

398

```scala

399

import scala.scalanative.unsigned._

400

401

// Division by zero throws ArithmeticException

402

val zero: UInt = 0.toUInt

403

try {

404

val result: UInt = 42.toUInt / zero

405

} catch {

406

case _: ArithmeticException => println("Division by zero")

407

}

408

409

// Large number handling

410

val large: ULong = Long.MaxValue.toULong

411

val doubled: ULong = large + large // Overflow wrapping

412

413

// Precision loss in conversions

414

val precise: ULong = ULong.MaxValue

415

val imprecise: Double = precise.toDouble // May lose precision

416

val recovered: ULong = imprecise.toLong.toULong // May not equal original

417

```

418

419

## Best Practices

420

421

1. **Use appropriate types**: Choose the smallest unsigned type that fits your data range

422

2. **Be aware of overflow**: Unsigned arithmetic wraps around on overflow

423

3. **Handle conversions carefully**: Converting between signed/unsigned can change values

424

4. **Use with C interop**: Unsigned types map directly to C unsigned types

425

5. **Check for division by zero**: Unlike some languages, Scala throws exceptions

426

6. **Consider precision**: Large unsigned values may lose precision when converted to floating point

427

7. **Use extension methods**: `.toUInt` style conversions are more readable than constructors