#rounding #round #simd #multiplier

无需 std round_mult

一个用于将数字向上或向下舍入到倍数的微小库

3 个版本

0.1.3 2023 年 7 月 19 日
0.1.2 2022 年 8 月 24 日
0.1.1 2022 年 8 月 19 日
0.1.0 2022 年 8 月 12 日

并发 中排名第 312


numscan 中使用

MIT/Apache

20KB
382

round_mult

一个将数字向上或向下舍入到倍数的微小库。

使用方法

该库有两个函数

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

它们都接受一个值和一个倍数,并分别将值向下或向上舍入到倍数。

倍数

有两种类型的倍数

示例

例如。

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

示例:SIMD

创建此库的主要动机是 SIMD 处理。特别是当数据长度不是 SIMD 通道数量的倍数时,这意味着您将会有一些剩余的数据需要处理,而这些数据无法使用 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;
	}
}

无运行时依赖项

~10KB