| Crates.io | round_mult |
| lib.rs | round_mult |
| version | 0.1.4 |
| created_at | 2022-08-12 11:32:27.720972+00 |
| updated_at | 2025-03-25 17:02:04.995229+00 |
| description | A tiny library to round a number up or down to a multiplier. |
| homepage | https://github.com/yehuthi/round_mult |
| repository | https://github.com/yehuthi/round_mult |
| max_upload_size | |
| id | 643957 |
| size | 41,358 |
A tiny library to round a number up or down to a multiplier.
The library has two functions:
round_mult::[up] (see note below)round_mult::[down]They both take a value and a multiplier and round the value down or up to the multiplier respectively.
[!NOTE] As of Rust 1.73.0, integer primitives have a built-in
next_multiple_ofmethod.
There are two kind of multipliers:
NonZeroPow2] When the multiplier is a power of two, it can be calculated faster. Prefer it when possible.std::num::NonZeroU_ for any multiplier value.E.g.
use std::num::NonZeroUsize;
use round_mult::NonZeroPow2;
assert_eq!(
round_mult::down(70usize, NonZeroPow2::v32()),
64
);
// These two are semantically equivalent:
assert_eq!(
round_mult::down(70usize, NonZeroPow2::new(32).unwrap()),
round_mult::down(70usize, NonZeroUsize::new(32).unwrap()),
);
// but NonZeroPow2 (the first parameter) is faster.
// However, it can't be used when the multiplier isn't a power of two.
// In that case use a NonZeroU_ type:
assert_eq!(
round_mult::down(109usize, NonZeroUsize::new(10).unwrap()),
100
);
assert_eq!(
round_mult::up(101usize, NonZeroUsize::new(10).unwrap()),
Some(110)
);
The main motivation for this library is SIMD processing. Specifically when the length of data isn't a multiple of the SIMD lanes count, which means you will have a remainder of data to process without SIMD.
use round_mult::NonZeroPow2;
fn f(data: &[u8]) {
// for this example, assume we want to use u8x32 SIMD. We could do:
// type Simd = std::simd::u8x32;
// let lanes = NonZeroPow2::of::<Simd>();
// but to keep this example compiling on stable, we could also use:
let lanes = NonZeroPow2::v32();
let mut i = 0;
while i < round_mult::down(data.len(), lanes) {
// SIMD process…
// let data = Simd::from_slice(s[i..]);
// etc. etc.
i += lanes.get();
}
while i < data.len() {
// remainder process…
i += 1;
}
}