2 个版本
0.1.1 | 2023 年 9 月 6 日 |
---|---|
0.1.0 | 2020 年 4 月 27 日 |
#1116 在 算法
17KB
191 行
通过存储其指数表示非负2的幂。
Pow2
类型的范围限制为 1 .. 2^255
(包含)。它是一个简单的包装器,围绕 u8
存储指数。
Pow2
通常用于对齐整数值,例如 I/O 缓冲区大小、页面大小等。
不支持负2的幂,因为它们在管理内存、快速乘法等应用中很少或没有应用。
Pow2
可以表示特定整数类型的范围之外的价值。例如,Pow2::from_exponent(40)
不能转换为 u32
。转换实现将这种方式与算术溢出类似处理;操作被定义,但可能在运行时失败。
可以定义一个 Pow2
变体系列,每个原始整数类型一个。然而,这种设计的用户体验可能不尽如人意;留待未来研究。
为 Pow2
定义的运算符是以2的幂的值定义的,而不是指数。例如,Pow2 * Pow2
的结果是指数相加,而不是指数相乘。
示例
const PAGE_SIZE: Pow2 = Pow2::from_exponent(12);
assert_eq!(u32::from(PAGE_SIZE), 0x1000);
let x: u32 = 0x1eee;
assert_eq!(PAGE_SIZE.align_down(x), 0x1000);
assert_eq!(PAGE_SIZE.align_up(x), Some(0x2000));
assert_eq!(PAGE_SIZE.align_up_unchecked(x), 0x2000);
可以使用 pow2_const!
宏来编写常量2的幂,使用值而不是指数。由于当前 const fns 的限制,pow2_const!
宏不检查输入是否是有效的2的幂。如果不是2的幂,则其行为是未定义的。
use pow2::{Pow2, pow2_const};
const PAGE_SIZE: Pow2 = pow2_const!(0x1000);
assert_eq!(PAGE_SIZE.exponent(), 12);
有符号示例
Pow2
与有符号类型一样可以与无符号类型一起使用。
use pow2::Pow2;
const ALIGN4: Pow2 = Pow2::from_exponent(2);
assert_eq!(ALIGN4.align_up(4i32), Some(4i32));
assert_eq!(ALIGN4.align_up(3i32), Some(4i32));
assert_eq!(ALIGN4.align_up(2i32), Some(4i32));
assert_eq!(ALIGN4.align_up(1i32), Some(4i32));
assert_eq!(ALIGN4.align_up(-0i32), Some(0i32));
assert_eq!(ALIGN4.align_up(-1i32), Some(0i32));
assert_eq!(ALIGN4.align_up(-2i32), Some(0i32));
assert_eq!(ALIGN4.align_up(-3i32), Some(0i32));
assert_eq!(ALIGN4.align_up(-4i32), Some(-4i32));
assert_eq!(ALIGN4.align_up(-5i32), Some(-4i32));
assert_eq!(ALIGN4.align_up(-6i32), Some(-4i32));
assert_eq!(ALIGN4.align_up(-7i32), Some(-4i32));
assert_eq!(ALIGN4.align_up(-8i32), Some(-8i32));
不安全代码示例
这个库不包含不安全的代码,但它可以被不安全代码用来操作指针。这是因为Rust允许安全代码操作不安全指针的值,但不能解引用它们。
use pow2::{Pow2, pow2_const};
const U32_ALIGN: Pow2 = Pow2::align_of::<u32>();
let array: [u32; 4] = [ 111, 222, 333, 444 ];
let item_0_address: *const u8 = &array[0] as *const u32 as *const u8;
let item_1_address: *const u8 = &array[1] as *const u32 as *const u8;
assert_eq!(
U32_ALIGN.align_up((item_0_address as usize + 1) as *const u8).unwrap(),
item_1_address
);
依赖项
~1–1.6MB
~28K SLoC