#uint #int #arbitrary

no-std aint

1 到 128 之间的任意宽度整数

1 个不稳定版本

0.1.0 2023 年 12 月 25 日

#651嵌入式开发

MIT/Apache

1MB
20K SLoC

Aint

Aint 是一个实现 1 到 127 之间非标准位宽整数的 crate。这些整数类型由下一个最大的内置 Rust 整数表示,但被限制在广告的位宽范围内和行为的范围内。也就是说,T::MINT::MAX,是期望的具有 N 位整数 T 的值,并且类似地,环绕、饱和和溢出行为与期望的虚构内置整数 TN 位行为相匹配。

示例

fn add(a: i13, b: i13) -> i13 {
    a + b
}

let x = i13!(100);
let y = add(x, i13!(-42));
assert_eq!(y, i13!(58));

有关详细信息,请参阅文档


lib.rs:

Aint 是一个实现 1 到 127 之间非标准位宽整数的 crate。这些整数类型由下一个最大的内置 Rust 整数表示,但被限制在广告的位宽范围内和行为的范围内。也就是说,T::MINT::MAX,是期望的具有 N 位整数 T 的值,并且类似地,环绕、饱和和溢出行为与期望的虚构内置整数 TN 位行为相匹配。

示例

fn add(a: i13, b: i13) -> i13 {
    a + b
}

let x = i13!(100);
let y = add(x, i13!(-42));
assert_eq!(y, i13!(58));

核心实现类型是 Aint<R, const WIDTH: u32>,它接受一个表示类型 R 和一个位宽 WIDTHAint 主要用作实现细节,不直接使用。相反,建议使用此 crate 提供的类型别名。

如果直接使用 Aint,它将只允许与该 crate 提供的现有类型别名匹配的泛型参数。例如,类型 i24Aint<i32, 24> 的别名。理论上,Aint<i64, 24> 将具有相同的功能,但如果实例化,将导致编译时错误。这防止了存在多个功能相同但与编译器不兼容的类型 Aint

字宽类型

具有精确字宽的整数类型提供了其他整数类型没有的额外方法和功能。这些类型的宽度是8的倍数,例如 i24(3字节)、u56(7字节)和 u120(15字节)。这些类型提供了字节和字节序操作的API,如内置Rust整数提供的 T::from_be_bytesT::swap_bytesT::to_le。由于这些方法的意义变得模糊,甚至可能毫无意义,因此其他整数类型不实现这些方法。

转换

此crate提供的所有整数类型都实现了将它们转换为和从所有内置Rust整数类型转换的特质。当转换不可失败时,将实现为 From,当转换可能失败时,将实现为 TryFrom。例如,从 i4 转换为 i8 是实现为 impl From<i4> for i8,但反向转换实现为 impl TryFrom<i8> for i4

遗憾的是,此crate不提供每种类型对之间相同的转换,例如从 i4 转换到 i13。标准转换特质的现有泛型实现阻止了这些特质的一般化实现,该实现将涵盖此crate提供的所有类型,并且由于极端的编译时间,为每种类型对单独实现转换是不切实际的,因为每种类型对都会导致128^2个特质实现。

此crate还提供了两种替代转换特质,它们执行不可失败的、但可能丢失数据的转换:WrappingFrom/WrappingIntoSaturatingFrom/SaturatingInto。这些特质对内置整数和此crate提供的整数的所有组合进行了实现。有关详细信息,请参阅每个特质的文档。

连接和拆分

此库还提供了两个用于按位连接和分割整数的特性:BitConcatBitSplit。任何两个整数类型都可以连接,只要它们的总位数不超过128位,任何整数都可以按位分割成两个整数,这两个整数的总位数等于原始整数的位数。

let x: u16 = 0b0101010100101_101;
let (x1, x2): (i13, u3) = x.bit_split();
let y = u16::bit_concat(x1, x2);

assert_eq!(x, y);
assert_eq!(x1, i13!(0b0101010100101));
assert_eq!(x2, u3!(0b101));

宏定义

此库提供的每个整数类型都包含宏,可以从字面量构造这些类型。内置整数可以有带类型的字面量,如 42u8-7i64。此库提供的宏执行类似的功能。 u13!(100) 实质上是一个 u13 字面量,其值为 100。这些宏提供的值也会在编译时进行检查,以确保它们对类型是有效的。例如,u4!(100) 将导致编译时错误,因为 u4 只能表示从 015 的值(包含0和15)。

特性

此库有两个非默认特性,分别是 serdenum,它们启用了与 serdenum 库的兼容性。

启用 serde 特性将为此库中的每个整数类型提供 serde::Serializeserde::Deserialize 的实现。

启用 num 特性将为 num 库家族中的所有适当特性提供实现,包括来自 num_traitsnum_integer 库的实现。

[dependencies]
aint = { version = "0.1", features = [ "serde", "num" ] }

no_std

此库也是 #![no_std]。与一些其他库不同,此库没有 std(或 no_std)特性 - 它根本不使用或需要 libstd。此外,此库也不使用 alloclibcore 是唯一的必需依赖项,并且 serdenum 特性中包含的库也兼容 no_std

依赖项

~225KB