round_mult

Crates.ioround_mult
lib.rsround_mult
version0.1.3
sourcesrc
created_at2022-08-12 11:32:27.720972
updated_at2023-07-19 14:00:59.57071
descriptionA tiny library to round a number up or down to a multiplier.
homepagehttps://github.com/yehuthi/round_mult
repositoryhttps://github.com/yehuthi/round_mult
max_upload_size
id643957
size20,222
Yehuthi (yehuthi)

documentation

README

round_mult

A tiny library to round a number up or down to a multiplier.

Usage

The library has two functions:

  • round_mult::[up]
  • round_mult::[down]

They both take a value and a multiplier and round the value down or up to the multiplier respectively.

Multiplier

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.

Example

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)
);

Example: SIMD

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;
	}
}
Commit count: 61

cargo fmt