一、源码
这段代码是Rust类型级编程中用于标记非零类型的系统,它通过特质(trait)NonZero 和一系列实现来确保类型安全。未来将扩展到小数和浮点数以拓宽其表示范围。
use crate::sealed::Sealed;
use crate::number::{Bit, Unsigned, types::{B1, UInt}};
/// 标记特质,标识非零类型(除B0、U0、Z0外)
pub trait NonZero: Sealed {}
// B1(位1)是非零值
impl NonZero for B1 {}
// UInt<U, B> 只要存在即为非零
impl<U: Unsigned, B: Bit> NonZero for UInt<U, B> {}
// 正整数PInt要求底层无符号类型非零
impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
// 负整数NInt要求底层无符号类型非零
impl<U: Unsigned + NonZero> NonZero for NInt<U> {}
二、代码解释
- 基本结构
use crate::sealed::Sealed;
use crate::number::{Bit, Unsigned, types::{B1, UInt}};
-
Sealed trait: 一个私有特质,防止下游crate实现这些特质,确保只有当前crate可以控制实现。
-
Bit: 表示二进制位(通常是B0或B1)。
-
Unsigned: 表示无符号整数类型(如U0, U1, U2等)。
-
UInt<U, B>: 无符号整数的类型级表示,其中U是高位部分,B是最低位(例如UInt<U1, B0>表示2)。
- NonZero trait
pub trait NonZero: Sealed {}
这是一个标记特质(marker trait),用于标识非零类型。它继承Sealed,确保只有当前crate可以实现它。
3. 具体实现
(a)B1(位1)是非零
impl NonZero for B1 {}
B1表示二进制位1,显然非零。
(b)UInt<U, B>(无符号整数)是非零
impl<U: Unsigned, B: Bit> NonZero for UInt<U, B> {}
UInt表示一个至少为1的正整数(例如UInt<U0, B1>是1),因此总是非零。
(c)正整数PInt要求底层无符号类型非零
impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
PInt表示正整数(如PInt表示+1),它要求底层的无符号类型U必须非零(即U: NonZero)。
(d)负整数NInt要求底层无符号类型非零
impl<U: Unsigned + NonZero> NonZero for NInt<U> {}
NInt表示负整数(如NInt表示-1),同样要求底层无符号类型U非零。
三、扩展到小数和浮点数
当前系统仅支持整数(包括正负整数和无符号整数)。要支持小数和浮点数,我们需要扩展类型系统。
- 表示小数(定点数)
我们可以用定点数表示小数,例如:
// 示例:Qm.n 格式(m位整数部分,n位小数部分)
struct FixedPoint<I, F> {
integer: I, // 整数部分(带符号)
fractional: F, // 小数部分(无符号)
}
要求:
-
整数部分I可以是PInt、NInt或Z0(零)。
-
小数部分F是一个无符号整数(表示小数位的值)。
实现NonZero:
-
当整数部分非零(I: NonZero)时,整个数非零。
-
如果整数部分为零,但小数部分非零(F: NonZero),那么整个数也非零。
impl<I, F> NonZero for FixedPoint<I, F>
where
I: NonZero, // 整数部分非零
F: Unsigned + NonZero, // 或小数部分非零
{}
- 表示浮点数(IEEE754风格)
浮点数更复杂,但我们可以用类型参数表示符号、指数和尾数:
struct Float<S, E, M> {
sign: S, // 符号(B0表示正,B1表示负)
exponent: E, // 指数(有偏)
mantissa: M, // 尾数(隐含前导1)
}
非零条件:
-
指数非全0(非规约数)或非全1(非无穷/NaN)。
-
尾数非零(对于规约数)。
但类型级编程中,我们需要用类型表示这些状态。例如:
// 规约数(exponent非全0且非全1,mantissa任意)
impl<S, E, M> NonZero for Float<S, E, M>
where
E: NotAllZeros + NotAllOnes, // 自定义特质,表示指数非全0且非全1
{}
// 非规约数(exponent全0,但mantissa非零)
impl<S, M> NonZero for Float<S, AllZeros, M>
where
M: NonZero, // 尾数非零
{}
-
扩展范围
小数(定点数):通过增加整数部分和小数部分的位数来扩展范围(例如FixedPoint<PInt, UInt<U5, B0>>表示整数部分10位,小数部分5位)。
浮点数:通过增加指数和尾数的位数来扩展范围和精度(例如半精度、单精度、双精度)。
四、总结
-
原代码通过NonZero特质标记非零整数类型(包括正负整数和无符号整数)。
-
扩展到小数(定点数)时,需要同时检查整数部分和小数部分。
-
扩展到浮点数时,需要根据指数和尾数的状态判断非零条件。
-
通过增加位数(类型参数)可以拓宽表示范围和提高精度。
这种类型级编程常用于嵌入式系统、数值计算和高安全性领域,在编译期确保数值有效性(如避免除零错误)。