bnum — библиотека для работы с обобщёнными числами, для которых на уровне типов зафиксированы: знаковость, число байт под хранение, битовая ширина и поведение при переполнении.
use bnum::prelude::*;
// imports common use items
// including the `Integer` type and the `n!` macro
// say we want to write a polynomial function
// which takes any unsigned or signed integer
// of any bit width and with any overflow behaviour
// for example, the polynomial could be p(x) = 2x^3 + 3x^2 + 5x + 7
fn p<const S: bool, const N: usize, const B: usize, const OM: u8>(x: Integer<S, N, B, OM>) -> Integer<S, N, B, OM> {
n!(2)*x.pow(3) + n!(3)*x.pow(2) + n!(5)*x + n!(7)
// type inference means we don't need to specify the width of the integers in the n! macro
}
// 2*10^3 + 3*10^2 + 5*10 + 7 = 2357
assert_eq!(p(n!(10U256)), n!(2357));
// evaluates p(10) as a 256-bit unsigned integer
type U24w = t!(U24w);
// 24-bit unsigned integer with wrapping arithmetic
type I1044s = t!(I1044s);
// 1044-bit signed integer with saturating arithmetic
type U753p = t!(U753p);
// 753-bit unsigned integer that panics on arithmetic overflow
let a = p(U24w::MAX); // result wraps around and doesn't panic
let b = p(I1044s::MAX); // result is too large to be represented by the type, so saturates to I044s::MAX
// let c = p(U753p::MAX); // this would result in panic due to overflow