Saturating integers
satint provides no_std, no-alloc integer wrapper types whose arithmetic
operators saturate at the destination type's numeric bounds.
The signed wrappers are Si8, Si16, Si32, Si64, Si128, and Sisize.
The unsigned wrappers are Su8, Su16, Su32, Su64, Su128, and Susize.
Each type has a matching const constructor function: si8, si16, sisize,
su8, su16, susize, and so on.
use ;
assert_eq!;
assert_eq!;
let mut health = MAX;
health += 1;
assert_eq!;
Types And Constructors
Wrappers are transparent newtypes around core::num::Saturating<T>. Use the
associated new constructor, the short free constructor, or From for the
matching primitive. Use into_inner to recover the primitive value.
use ;
let signed = new;
let also_signed = si16;
let unsigned = from;
let pointer_sized = sisize + susize;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Each wrapper provides BITS, MIN, MAX, ZERO, and ONE.
use ;
assert_eq!;
assert_eq!;
assert_eq!;
Arithmetic
+, -, *, and signed unary - use saturating arithmetic. Assignment forms
such as += and *= have the same behavior. The left-hand side determines the
output type, so cross-width arithmetic clamps to the left-hand side's range.
use ;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
let mut value = new;
value += new;
value *= 3;
assert_eq!;
Mixed signed/unsigned addition and subtraction are supported for wrapper and primitive right-hand sides. Mixed signed/unsigned multiplication is not.
use ;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Left shifts saturate when bits would be shifted out of range. Right shifts match the primitive integer behavior, except oversized unsigned shifts produce zero and oversized signed shifts extend the sign.
use ;
assert_eq!;
assert_eq!;
assert_eq!;
Bitwise &, |, ^, and ! are available for another value of the same
wrapper type or the matching primitive type.
use ;
let mask = su8;
assert_eq!;
assert_eq!;
assert_eq!;
Division And Remainder
The inherent checked_* methods accept the same wrapper type and return
Option.
use ;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
The TryDiv, TryRem, TryDivAssign, and TryRemAssign traits accept any
same-sign wrapper width or same-sign primitive right-hand side and return
Result<_, DivError>.
use ;
assert_eq!;
assert_eq!;
assert_eq!;
let mut value = new;
value.try_div_assign.unwrap;
assert_eq!;
With the optional panicking-ops feature, /, %, /=, and %= are also
implemented. Those operators panic on zero divisors just like primitive integer
division.
Conversions
Use From and Into for conversions that cannot lose information.
use ;
let signed: Si32 = si8.into;
let unsigned: Su32 = su8.into;
let primitive: u32 = unsigned.into;
assert_eq!;
assert_eq!;
Use SaturatingFrom or SaturatingInto when the source may not fit. These
traits clamp to the destination range. Signed-to-unsigned conversions clamp
negative values to zero. The traits are implemented between all primitive
integer types, between wrappers, and between wrappers and primitive integers.
use ;
let unsigned: Su8 = su16.saturating_into;
let signed: Si8 = si16.saturating_into;
let from_primitive = saturating_from;
let primitive: u8 = u8saturating_from;
let narrowed: i8 = i16MAX.saturating_into;
let non_negative: usize = isizeMIN.saturating_into;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Same-width signedness conversions also have inherent saturating helpers.
use ;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Floating-point sources can be converted into primitive integers or wrappers with
SaturatingFrom and SaturatingInto. These conversions use Rust's as cast
behavior: finite values truncate toward zero, out-of-range values clamp, and
NaN becomes zero.
use ;
let primitive: i8 = 200.0_f32.saturating_into;
let unsigned_primitive = u8saturating_from;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Wrapper-to-float From impls are provided only where every source value is
represented exactly: Si8, Si16, Su8, and Su16 convert to f32; those
types plus Si32 and Su32 convert to f64.
use ;
let as_f32: f32 = si16.into;
let as_f64: f64 = su32.into;
assert_eq!;
assert_eq!;
Numeric Helpers
Wrappers expose many primitive integer helpers, returning wrapper values when the primitive method would return an integer of the same type.
use ;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Common bit, endian, checked division/remainder, power, and integer logarithm helpers mirror primitive integer methods.
use ;
let value = su16;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert!;
assert!;
Iterators
Sum and Product are implemented for scalar values and references.
use ;
let values = ;
assert_eq!;
assert_eq!;
Optional Features
The serde feature serializes and deserializes wrappers as their inner
primitive integer values.
The rand feature implements rand 0.10 uniform sampling for every wrapper.
use ;
use ;
let mut rng = seed_from_u64;
let signed = rng.random_range;
assert!;
assert!;
let unsigned = rng.random_range;
assert!;
assert!;
no_std
satint is #![no_std], does not use alloc, and forbids unsafe code.
License
Licensed under either of MIT or Apache-2.0, at your option.