#integer #unaligned #misaligned #const-generics

no-std arbitrary-int

u2, u3, u4, ..., u127的现代轻量级实现

10个稳定版本

1.2.7 2024年2月6日
1.2.6 2023年5月29日
1.2.4 2023年4月18日
1.2.3 2022年12月16日
1.2.0 2022年8月23日

嵌入式开发中排名44

Download history 3188/week @ 2024-04-20 3412/week @ 2024-04-27 2413/week @ 2024-05-04 2002/week @ 2024-05-11 3248/week @ 2024-05-18 2274/week @ 2024-05-25 2199/week @ 2024-06-01 2793/week @ 2024-06-08 3091/week @ 2024-06-15 3674/week @ 2024-06-22 2990/week @ 2024-06-29 2634/week @ 2024-07-06 2775/week @ 2024-07-13 3535/week @ 2024-07-20 4365/week @ 2024-07-27 3612/week @ 2024-08-03

每月下载量14,736
24个Crates使用(其中7 直接使用)

MIT许可证

60KB
1K SLoC

arbitrary-int

此crate实现了Rust的任意数字。一旦引入,您就可以使用如u5u120这样的类型。

为什么还需要另一个任意整数crate?

与此类似有很多crate(最著名的是https://crates.io/crates/ux)。试用了几种之后,我意识到它们都很重:它们创建了很多类,编译需要几秒钟。

此crate旨在非常简短,使用const generics。而不是引入约123个新结构体,此crate只引入了5个(一个用于u8u16u32u64u128),并使用const generics进行特定位深度的处理。它确实引入了123个新的类型别名(u1u2等),但这些对编译器的压力并不大。

此外,它的大多数函数都是const,因此它们可以在const上下文中使用。

如何使用

与原始数据类型如u32不同,没有内置语法(Rust不允许这样做)。实例创建如下

let value9 = u9::new(30);

这将创建一个9位的值。如果传递给new()的值不合适,则会引发panic!。这意味着接受u9作为参数的函数可以确定其内容永远不会大于u9

标准运算符都进行了重载,因此可以使用此类型进行计算。请注意,加法和减法(至少在调试模式下)执行边界检查。如果这不受欢迎,请参阅下面的num-traits章节。

内部,u9 将在其数据中存储一个 u16。可以获取此值

let value9 = u9::new(30).value();

基础数据类型

此包定义了类型 u1u2、...、u126u127(跳过了常规的 u8u16u32u64u128)。这些类型中的每一个都将其实际数据存储在下一个更大的数据类型中(例如,一个 u14 在内部有一个 u16,一个 u120 在内部有一个 u128)。然而,uXX 只是类型别名;也可以使用实际的底层泛型结构体

let a = UInt::<u8, 5>::new(0b10101));
let b = UInt::<u32, 5>::new(0b10101));

在这个例子中,a 将有 5 位,并以一个 u8 表示。这与 u5 相同。然而,b 由一个 u32 表示,因此它与 u5 是不同类型。

提取

任意整数的常见来源是从位字段中提取它们。例如,如果数据包含 32 位,并且我们想提取位 4..=9,我们可以执行以下操作

let a = u6::new(((data >> 4) & 0b111111) as u8);

这是一个相当常见的操作,但很容易出错:1 的数量和 u6 必须匹配。此外,new() 在内部将执行范围检查,这可能引发恐慌。第三,通常需要类型转换。为了使这更容易,存在各种提取方法,例如处理移位和掩码

let a = u6::extract_u32(data, 4);
let b = u12::extract_u128(data2, 63);

num-traits

默认情况下,任意整数不需要其他特质。但是,它对 num-traits 有可选支持。它实现了 WrappingAddWrappingSub,与常规加法和减法不同,它们不执行范围检查。

依赖关系

~0–255KB