silk.num.numeric.
Generic helpers and numeric contracts for algorithms over primitive numbers.
When to use#
Bound a type parameter with Zero or One when generic code needs the additive or
multiplicative identity of its number type, and with Float when it needs square roots,
trigonometry, or other binary floating-point operations. Call Numeric.add to add two values
of any primitive number type from generic code. Use the concrete number modules directly when an
algorithm also needs width-specific conversion, overflow, bitwise, or formatting operations.
Details#
Every primitive integer and float type conforms to Zero and One. Only f32 and f64
conform to Float, whose operations call the functions of silk.num.f32 and silk.num.f64.
A library number type, such as a fixed-point type, can conform in its own module. The helpers
bound their type parameter with these interfaces or with the operator interfaces of
silk.core.ops, such as T: Add<T, T>. The compiler selects the conformance during
specialization. A helper adds no effect requirement and no runtime dispatch.
Gotchas#
Each helper keeps the overflow rule of the operator. Integer addition traps if the result is outside the range of the type.
Examples#
Add values through one generic contract#
import silk.num.numeric { Numeric }
import silk.core.ops { Add }
fn total<T: Add<T, T>>(first: T, second: T, third: T) -> T {
let partial = Numeric.add<T>(move first, move second)
return Numeric.add<T>(move partial, move third)
}
pub fn main() -> i32 {
let small: u8 = total<u8>(1, 2, 3)
let large: i64 = total<i64>(40, 1, 1)
if small != 6 || large != 42 {
return 1
}
return 0
}Compute a length for any float type#
import silk.num.numeric { Float }
import silk.core.ops { Add, Multiply }
import silk.core.ownership { Copy }
fn length<T: Copy + Float + Add<T, T> + Multiply<T, T>>(x: T, y: T) -> T {
return Float.sqrt(x * x + y * y)
}
pub fn main() -> i32 {
let wide: f64 = length<f64>(3.0, 4.0)
let narrow: f32 = length<f32>(6.0, 8.0)
if wide != 5.0 || narrow != 10.0 {
return 1
}
return 0
}Import as Numeric with import silk.num.numeric { Numeric }.
Public declarations: 4.
Numeric#
pub struct NumericThe owner type of the generic numeric helpers. It has no fields and is never constructed.
Implementation Numeric#
impl NumericAssociated function add#
pub fn add<T: Add<T, T>>(left: T, right: T) -> TReturns left + right for any type T that has the + operator.
When to use#
Use add in generic code, or to pass addition as a named function.
Gotchas#
For an integer type, the program traps if the sum is outside the range of T.
Associated function zero#
pub fn zero<T: Zero>() -> TReturns the additive identity of T, such as 0 for an integer type or 0.0 for a float.
When to use#
Use zero when code must name the zero of a type that it writes as an argument, such as
Numeric.zero<i32>(). Inside a generic body that bounds T: Zero, Zero.zero() gives the
same value.
Associated function one#
pub fn one<T: One>() -> TReturns the multiplicative identity of T, such as 1 for an integer type or 1.0 for a
float.
When to use#
Use one when code must name the one of a type that it writes as an argument, such as
Numeric.one<f32>(). Inside a generic body that bounds T: One, One.one() gives the same
value.
Zero#
pub interface ZeroThe additive identity of a number type.
When to use#
Bound a type parameter with Zero when generic code must start a sum, build an origin, or test
for zero without a literal of the concrete type.
Details#
Every primitive integer type returns 0, and f32 and f64 return positive zero. A library
number type, such as a fixed-point type, can implement Zero in its own module.
Operation zero#
fn zero() -> SelfReturns the value that leaves any other value unchanged under addition.
One#
pub interface OneThe multiplicative identity of a number type.
When to use#
Bound a type parameter with One when generic code must build an identity transform, a unit
scale, or another value that needs 1 of the concrete type.
Details#
Every primitive integer type returns 1, and f32 and f64 return 1.0. A library number
type, such as a fixed-point type, can implement One in its own module.
Operation one#
fn one() -> SelfReturns the value that leaves any other value unchanged under multiplication.
Float#
pub interface FloatThe binary floating-point operations that generic geometry and numeric code needs.
When to use#
Bound a type parameter with Float when generic code needs square roots, trigonometry,
rounding, or finiteness tests and must work for both f32 and f64.
Details#
f32 and f64 conform, and each operation calls the function of the same name in
silk.num.f32 or silk.num.f64. So each operation returns the same bits on every target and
gives the canonical quiet NaN for every NaN result. Angles are in radians.
Gotchas#
Float does not include Zero or One. Bound with T: Float + Zero + One when generic code
also needs those values.
Operation sqrt#
fn sqrt(value: Self) -> SelfReturns the square root of value. Negative nonzero inputs and NaN return NaN.
Operation abs#
fn abs(value: Self) -> SelfReturns the magnitude of value, which clears the sign bit.
Operation floor#
fn floor(value: Self) -> SelfReturns the largest integer value that is not greater than value.
Operation ceil#
fn ceil(value: Self) -> SelfReturns the smallest integer value that is not less than value.
Operation round#
fn round(value: Self) -> SelfReturns the nearest integer value to value, with halfway cases away from zero.
Operation trunc#
fn trunc(value: Self) -> SelfReturns the integer part of value, which discards the fraction toward zero.
Operation min#
fn min(left: Self, right: Self) -> SelfReturns the smaller of left and right, with negative zero below positive zero. A NaN
operand gives NaN.
Operation max#
fn max(left: Self, right: Self) -> SelfReturns the larger of left and right, with positive zero above negative zero. A NaN
operand gives NaN.
Operation sin#
fn sin(value: Self) -> SelfReturns the sine of value, an angle in radians.
Operation cos#
fn cos(value: Self) -> SelfReturns the cosine of value, an angle in radians.
Operation tan#
fn tan(value: Self) -> SelfReturns the tangent of value, an angle in radians.
Operation atan2#
fn atan2(y: Self, x: Self) -> SelfReturns the angle in radians from the positive x axis to the point (x, y), in [-pi, pi].
Operation hypot#
fn hypot(x: Self, y: Self) -> SelfReturns sqrt(x * x + y * y) without overflow or underflow in the intermediate squares.
Operation fma#
fn fma(left: Self, right: Self, addend: Self) -> SelfReturns left * right + addend with one rounding.
Operation isFinite#
fn isFinite(value: Self) -> boolReturns true when value is neither infinite nor NaN.
Operation isNaN#
fn isNaN(value: Self) -> boolReturns true when value is NaN.
Implementation Zero for u8#
impl Zero for u8Operation zero#
fn zero() -> u8Implementation Zero for u16#
impl Zero for u16Operation zero#
fn zero() -> u16Implementation Zero for u32#
impl Zero for u32Operation zero#
fn zero() -> u32Implementation Zero for u64#
impl Zero for u64Operation zero#
fn zero() -> u64Implementation Zero for usize#
impl Zero for usizeOperation zero#
fn zero() -> usizeImplementation Zero for i8#
impl Zero for i8Operation zero#
fn zero() -> i8Implementation Zero for i16#
impl Zero for i16Operation zero#
fn zero() -> i16Implementation Zero for i32#
impl Zero for i32Operation zero#
fn zero() -> i32Implementation Zero for i64#
impl Zero for i64Operation zero#
fn zero() -> i64Implementation Zero for isize#
impl Zero for isizeOperation zero#
fn zero() -> isizeImplementation Zero for f32#
impl Zero for f32Operation zero#
fn zero() -> f32Implementation Zero for f64#
impl Zero for f64Operation zero#
fn zero() -> f64Implementation One for u8#
impl One for u8Operation one#
fn one() -> u8Implementation One for u16#
impl One for u16Operation one#
fn one() -> u16Implementation One for u32#
impl One for u32Operation one#
fn one() -> u32Implementation One for u64#
impl One for u64Operation one#
fn one() -> u64Implementation One for usize#
impl One for usizeOperation one#
fn one() -> usizeImplementation One for i8#
impl One for i8Operation one#
fn one() -> i8Implementation One for i16#
impl One for i16Operation one#
fn one() -> i16Implementation One for i32#
impl One for i32Operation one#
fn one() -> i32Implementation One for i64#
impl One for i64Operation one#
fn one() -> i64Implementation One for isize#
impl One for isizeOperation one#
fn one() -> isizeImplementation One for f32#
impl One for f32Operation one#
fn one() -> f32Implementation One for f64#
impl One for f64Operation one#
fn one() -> f64Implementation Float for f32#
impl Float for f32Operation sqrt#
fn sqrt(value: f32) -> f32Operation abs#
fn abs(value: f32) -> f32Operation floor#
fn floor(value: f32) -> f32Operation ceil#
fn ceil(value: f32) -> f32Operation round#
fn round(value: f32) -> f32Operation trunc#
fn trunc(value: f32) -> f32Operation sin#
fn sin(value: f32) -> f32Operation cos#
fn cos(value: f32) -> f32Operation tan#
fn tan(value: f32) -> f32Operation min#
fn min(left: f32, right: f32) -> f32Operation max#
fn max(left: f32, right: f32) -> f32Operation atan2#
fn atan2(y: f32, x: f32) -> f32Operation hypot#
fn hypot(x: f32, y: f32) -> f32Operation fma#
fn fma(left: f32, right: f32, addend: f32) -> f32Operation isFinite#
fn isFinite(value: f32) -> boolOperation isNaN#
fn isNaN(value: f32) -> boolImplementation Float for f64#
impl Float for f64Operation sqrt#
fn sqrt(value: f64) -> f64Operation abs#
fn abs(value: f64) -> f64Operation floor#
fn floor(value: f64) -> f64Operation ceil#
fn ceil(value: f64) -> f64Operation round#
fn round(value: f64) -> f64Operation trunc#
fn trunc(value: f64) -> f64Operation sin#
fn sin(value: f64) -> f64Operation cos#
fn cos(value: f64) -> f64Operation tan#
fn tan(value: f64) -> f64Operation min#
fn min(left: f64, right: f64) -> f64Operation max#
fn max(left: f64, right: f64) -> f64Operation atan2#
fn atan2(y: f64, x: f64) -> f64Operation hypot#
fn hypot(x: f64, y: f64) -> f64Operation fma#
fn fma(left: f64, right: f64, addend: f64) -> f64Operation isFinite#
fn isFinite(value: f64) -> boolOperation isNaN#
fn isNaN(value: f64) -> boolCategory: Numbers.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.