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 of 0.0 / 0.0, sqrt(-1), etc.
  • infinity / -infinity — overflow or 1.0 / 0.0.
  • Negative zero compares equal to positive zero but produces -infinity when 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 of 0.0 / 0.0, sqrt(-1), etc.
  • infinity / -infinity — overflow or 1.0 / 0.0.
  • Negative zero compares equal to positive zero but produces -infinity when 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.