Module
std.numeric
Protocols
public protocol RandomNumberGenerator
A source of pseudo-random UInt64 values. Implementers expose a single
raw-uniform primitive; the extension on this protocol layers ergonomic
helpers on top.
Conformers are free to choose any algorithm they like — the protocol
makes no statement about cryptographic strength, period, or bias. Pick
Lcg64 for cheap non-cryptographic randomness; bring your own type for
anything stronger.
Examples
struct MyRng: RandomNumberGenerator {
var state: UInt64;
mutating func nextUInt64() -> UInt64 {
// mix state, return a fresh value
}
}public protocol SignedInteger
Marker protocol for signed integer types. The abs() requirement is
what justifies treating these uniformly in generic code — unsigned
integers can't satisfy it without changing semantics.
public protocol Steppable
A type whose values can be stepped one position at a time. Underpins
for-in over integer ranges and any other "next/previous" walk where
the step size is implicit (1 for integers).
successor and predecessor should be inverses for every interior
value; behaviour at the type's edges (Int64.maxValue.successor(),
for example) follows the same wrapping rules as add/subtract.
public protocol UnsignedInteger
Marker protocol for unsigned integer types. Carries no requirements —
it exists so generic code can constrain on signedness without naming
every concrete UInt* type.
Structs
public struct Float32 { /* private fields */ }
A 32-bit IEEE 754 single-precision float.
Range is approximately ±3.4×10^38 with 6-9 significant decimal
digits. Float literals without a type annotation default to Float64;
annotate the binding to pick Float32. The type is FFISafe and lays out
as a single lang.f32.
Examples
let pi = Float64.pi;
let area = pi * radius * radius;
let s = area.format(.{precision: 2}); // "314.16"
let x = 3.14; // Float64
let y: Float32 = 3.14; // Float32
Special Values
nan— Not-a-Number, result of0.0 / 0.0,sqrt(-1), etc.infinity/-infinity— overflow or1.0 / 0.0.- Negative zero compares equal to positive zero but produces
-infinitywhen used as a divisor.
NaN comparisons are surprising: nan == nan is false and every ordered
comparison against NaN is false. Use isNaN to test, never == nan. Any
arithmetic with NaN propagates NaN.
Representation
A single lang.f32 field holding the raw IEEE 754 bit pattern.
public struct Float64 { /* private fields */ }
A 64-bit IEEE 754 double-precision float.
Range is approximately ±1.8×10^308 with 15-17 significant decimal
digits. Float literals without a type annotation default to Float64;
annotate the binding to pick Float32. The type is FFISafe and lays out
as a single lang.f64.
Examples
let pi = Float64.pi;
let area = pi * radius * radius;
let s = area.format(.{precision: 2}); // "314.16"
let x = 3.14; // Float64
let y: Float32 = 3.14; // Float32
Special Values
nan— Not-a-Number, result of0.0 / 0.0,sqrt(-1), etc.infinity/-infinity— overflow or1.0 / 0.0.- Negative zero compares equal to positive zero but produces
-infinitywhen used as a divisor.
NaN comparisons are surprising: nan == nan is false and every ordered
comparison against NaN is false. Use isNaN to test, never == nan. Any
arithmetic with NaN propagates NaN.
Representation
A single lang.f64 field holding the raw IEEE 754 bit pattern.
public struct Int16 { /* private fields */ }
A 16-bit signed integer.
Int16 is the 16-bit member of the integer family. The same surface
area is provided across all widths; switch widths to trade range for memory
or to match an FFI ABI. Arithmetic wraps on overflow by default — use the
*Checked variants for overflow detection or *Saturating to clamp to
minValue/maxValue. The type is FFISafe and lays out as a single
lang.i16 so it can cross C boundaries unchanged.
Examples
let a: Int64 = 100;
let b = a + 50; // 150
let c = a * 2; // 200
let d = a.addChecked(Int64.maxValue); // None (overflow detected)
// Bit twiddling
(0b1010).countOnes // 2
(1).shiftLeft(by: 4) // 16
(-1).leadingZeros // 0 (all bits set)
Representation
A single lang.i16 field. No padding, no headers — bit-identical
to the corresponding C type.
public struct Int32 { /* private fields */ }
A 32-bit signed integer.
Int32 is the 32-bit member of the integer family. The same surface
area is provided across all widths; switch widths to trade range for memory
or to match an FFI ABI. Arithmetic wraps on overflow by default — use the
*Checked variants for overflow detection or *Saturating to clamp to
minValue/maxValue. The type is FFISafe and lays out as a single
lang.i32 so it can cross C boundaries unchanged.
Examples
let a: Int64 = 100;
let b = a + 50; // 150
let c = a * 2; // 200
let d = a.addChecked(Int64.maxValue); // None (overflow detected)
// Bit twiddling
(0b1010).countOnes // 2
(1).shiftLeft(by: 4) // 16
(-1).leadingZeros // 0 (all bits set)
Representation
A single lang.i32 field. No padding, no headers — bit-identical
to the corresponding C type.
public struct Int64 { /* private fields */ }
A 64-bit signed integer.
Int64 is the 64-bit member of the integer family. The same surface
area is provided across all widths; switch widths to trade range for memory
or to match an FFI ABI. Arithmetic wraps on overflow by default — use the
*Checked variants for overflow detection or *Saturating to clamp to
minValue/maxValue. The type is FFISafe and lays out as a single
lang.i64 so it can cross C boundaries unchanged.
Examples
let a: Int64 = 100;
let b = a + 50; // 150
let c = a * 2; // 200
let d = a.addChecked(Int64.maxValue); // None (overflow detected)
// Bit twiddling
(0b1010).countOnes // 2
(1).shiftLeft(by: 4) // 16
(-1).leadingZeros // 0 (all bits set)
Representation
A single lang.i64 field. No padding, no headers — bit-identical
to the corresponding C type.
public struct Int8 { /* private fields */ }
A 8-bit signed integer.
Int8 is the 8-bit member of the integer family. The same surface
area is provided across all widths; switch widths to trade range for memory
or to match an FFI ABI. Arithmetic wraps on overflow by default — use the
*Checked variants for overflow detection or *Saturating to clamp to
minValue/maxValue. The type is FFISafe and lays out as a single
lang.i8 so it can cross C boundaries unchanged.
Examples
let a: Int64 = 100;
let b = a + 50; // 150
let c = a * 2; // 200
let d = a.addChecked(Int64.maxValue); // None (overflow detected)
// Bit twiddling
(0b1010).countOnes // 2
(1).shiftLeft(by: 4) // 16
(-1).leadingZeros // 0 (all bits set)
Representation
A single lang.i8 field. No padding, no headers — bit-identical
to the corresponding C type.
public struct Lcg64 { /* private fields */ }
A 64-bit linear congruential generator. Cheap, allocation-free, and adequate for shuffling, fuzz seeds, and simulation noise — not for cryptographic use, key generation, or anything an adversary observes.
Constants come from Numerical Recipes and give a full period of 2^64:
- multiplier
a = 6364136223846793005 - increment
c = 1442695040888963407
The state update is state = state * a + c, returning the new state.
Examples
var rng = Lcg64(seed: 12345);
let v1 = rng.nextUInt64();
let v2 = rng.nextUInt64(); // distinct from v1
Representation
One UInt64 field — the mutable generator state.
public struct UInt16 { /* private fields */ }
A 16-bit unsigned integer.
UInt16 is the 16-bit member of the integer family. The same surface
area is provided across all widths; switch widths to trade range for memory
or to match an FFI ABI. Arithmetic wraps on overflow by default — use the
*Checked variants for overflow detection or *Saturating to clamp to
minValue/maxValue. The type is FFISafe and lays out as a single
lang.i16 so it can cross C boundaries unchanged.
Examples
let a: Int64 = 100;
let b = a + 50; // 150
let c = a * 2; // 200
let d = a.addChecked(Int64.maxValue); // None (overflow detected)
// Bit twiddling
(0b1010).countOnes // 2
(1).shiftLeft(by: 4) // 16
(-1).leadingZeros // 0 (all bits set)
Representation
A single lang.i16 field. No padding, no headers — bit-identical
to the corresponding C type.
public struct UInt32 { /* private fields */ }
A 32-bit unsigned integer.
UInt32 is the 32-bit member of the integer family. The same surface
area is provided across all widths; switch widths to trade range for memory
or to match an FFI ABI. Arithmetic wraps on overflow by default — use the
*Checked variants for overflow detection or *Saturating to clamp to
minValue/maxValue. The type is FFISafe and lays out as a single
lang.i32 so it can cross C boundaries unchanged.
Examples
let a: Int64 = 100;
let b = a + 50; // 150
let c = a * 2; // 200
let d = a.addChecked(Int64.maxValue); // None (overflow detected)
// Bit twiddling
(0b1010).countOnes // 2
(1).shiftLeft(by: 4) // 16
(-1).leadingZeros // 0 (all bits set)
Representation
A single lang.i32 field. No padding, no headers — bit-identical
to the corresponding C type.
public struct UInt64 { /* private fields */ }
A 64-bit unsigned integer.
UInt64 is the 64-bit member of the integer family. The same surface
area is provided across all widths; switch widths to trade range for memory
or to match an FFI ABI. Arithmetic wraps on overflow by default — use the
*Checked variants for overflow detection or *Saturating to clamp to
minValue/maxValue. The type is FFISafe and lays out as a single
lang.i64 so it can cross C boundaries unchanged.
Examples
let a: Int64 = 100;
let b = a + 50; // 150
let c = a * 2; // 200
let d = a.addChecked(Int64.maxValue); // None (overflow detected)
// Bit twiddling
(0b1010).countOnes // 2
(1).shiftLeft(by: 4) // 16
(-1).leadingZeros // 0 (all bits set)
Representation
A single lang.i64 field. No padding, no headers — bit-identical
to the corresponding C type.
public struct UInt8 { /* private fields */ }
A 8-bit unsigned integer.
UInt8 is the 8-bit member of the integer family. The same surface
area is provided across all widths; switch widths to trade range for memory
or to match an FFI ABI. Arithmetic wraps on overflow by default — use the
*Checked variants for overflow detection or *Saturating to clamp to
minValue/maxValue. The type is FFISafe and lays out as a single
lang.i8 so it can cross C boundaries unchanged.
Examples
let a: Int64 = 100;
let b = a + 50; // 150
let c = a * 2; // 200
let d = a.addChecked(Int64.maxValue); // None (overflow detected)
// Bit twiddling
(0b1010).countOnes // 2
(1).shiftLeft(by: 4) // 16
(-1).leadingZeros // 0 (all bits set)
Representation
A single lang.i8 field. No padding, no headers — bit-identical
to the corresponding C type.
Type Aliases
public type Float = Float64
Default floating-point type — alias for Float64. Reach for Float
when you want the recommended precision/performance trade-off; reach for
Float32 only when you specifically need 32-bit storage.
public type Int = Int64
Platform-sized signed integer — currently always Int64.
public type UInt = UInt64
Platform-sized unsigned integer — currently always UInt64.