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