PhysUnits】15.2 引入P1后的减一特质(sub1.rs)
一、源码
代码实现了类型系统中的"减一"操作(Sub1 trait),与前文的"加一"操作相对应。
//! 减一操作特质实现 / Decrement operation trait implementation
//! 说明:
//! 1. Z0、P1,、N1 - 1,常规计算
//! 2. B0<H> - 1,该位B1,有借位,当H-1 = N1时要规范格式,即H=Z0时要特化,此时源码为B0<Z0>,不是简化格式
//! 3. B1<H> - 1,该位B0,无借位,原高位是Z0时要规范格式,即H=Z0时要特化,此时源码为B1<Z0>,已经被P1替代
//! 4. 目前B1<Z0>已经用P1替换,高位H已经不可能为Z0,2条格式已经不存在,3条在H=P1时提前特化use super::basic::{B0, B1, Z0, P1, N1, NonZero, NonOne};/// 减一特质 / Decrement trait
///
/// 为类型系统提供减一操作的计算能力
/// Provides decrement operation capability for type system
pub trait Sub1 {/// 减一后的输出类型 / Output type after decrementtype Output;
}// ========== 基础类型实现 / Basic Type Implementations ==========/// Z0 (0) 减一实现 / Decrement for Z0 (0)
///
/// 0 - 1 = -1 (N1)
impl Sub1 for Z0 {type Output = N1;
}/// P1(原B1<Z0>)(+1) 减一特化实现 / Specialized decrement for P1 (+1)
///
impl Sub1 for P1 {type Output = Z0;
}/// N1 (-1) 减一实现 / Decrement for N1 (-1)
///
/// -1 - 1 = -2 (B0<N1>)
impl Sub1 for N1 {type Output = B0<N1>;
}
// ========== 递归类型实现 / Recursive Type Implementations ==========/// B0<H> 减一实现 / Decrement for B0<H>
///
/// 处理借位情况 / Handles borrow case
/// ...0 -1 = ...1(高位借位) / ...0 -1 = ...1(with borrow)
impl<H: NonZero + NonOne + Sub1> Sub1 for B0<H>{//引入P1后,高位不可能是Z0type Output = B1<H::Output>;
}/// B1<H> 减一实现 / Decrement for B1<H>
///
/// 直接减一无需借位 / Direct decrement without borrow
/// ...1 -1 = ...0 / ...1 -1 = ...0
impl<H: NonZero + NonOne> Sub1 for B1<H>{//引入P1后,高位不可能是Z0type Output = B0<H>;
}// ========== 特化实现 ==========
// B1<P1>特化
impl Sub1 for B1<P1>{type Output = B0<P1>;
}// B0<P1>特化
impl Sub1 for B0<P1>{type Output = P1;
}
二、核心设计
-
Sub1 trait:定义了一个关联类型 Output 表示减一后的结果类型
-
分层实现:
-
基础类型实现(Z0, P1, N1)
-
递归类型实现(B0, B1)
-
特化实现(处理特定边界情况)
三、基础类型实现
- Z0 (零) 减一
impl Sub1 for Z0 {type Output = N1; // 0 - 1 = -1
}
- P1 (正一) 减一
impl Sub1 for P1 {type Output = Z0; // 1 - 1 = 0
}
注意这里 P1 替代了原先的 B1
- N1 (负一) 减一
impl Sub1 for N1 {type Output = B0<N1>; // -1 - 1 = -2
}
- B0 表示二进制形式的 -2
四、递归类型实现
- B0 减一(需要借位)
impl<H: NonZero + NonOne + Sub1> Sub1 for B0<H> {type Output = B1<H::Output>; // ...0 -1 = ...1 (需要借位)
}
-
将最低位从0变为1,并向高位借位
-
约束 H 必须是非零、非一且可减一
- B1 减一(无需借位)
impl<H: NonZero + NonOne> Sub1 for B1<H> {type Output = B0<H>; // ...1 -1 = ...0
}
-
将最低位从1变为0,不需要借位
-
约束 H 必须是非零且非一
五、特化实现
- B1 减一
impl Sub1 for B1<P1> {type Output = B0<P1>; // 3 (B1<P1>) -1 = 2 (B0<P1>)
}
-
处理 P1 作为高位时的特殊情况
-
二进制表示:B1 是 11 (3),减一得 10 (2)
- B0 减一
impl Sub1 for B0<P1> {type Output = P1; // 2 (B0<P1>) -1 = 1 (P1)
}
-
二进制表示:B0 是 10 (2),减一得 01 (1)
-
这里直接返回 P1 而不是 B1,保持了规范化
六、关键点说明
- 二进制表示与借位:
-
类似于二进制减法,当减数大于被减数时需要借位
-
例如 B0 表示最低位是0,减一需要从高位借位
- 规范化处理:
-
使用 P1 直接表示 +1,而不是 B1
-
避免了 B1 和 B0 等不规范表示
-
可以很好地区分0和正数
- 类型约束:
-
NonZero:确保不会对零进行递归操作
-
NonOne:确保不会对一进行递归操作(因为 P1 已经有特化代码)
- 边界情况处理:
-
对 B1 和 B0 进行了特化实现
-
确保结果保持最简形式
七、示例计算
- P1 (1) 减一:
P1 -1 => Z0
- B0 (2) 减一:
B0<P1> -1 => P1
- B1 (3) 减一:
B1<P1> -1 => B0<P1>
- B0 (-2) 减一(通过递归):
B0<N1> -1 => B1<N1::Output> => B1<B0<N1>> // 表示 -3
这种设计使得类型系统可以在编译期完成数字的减法运算,与加法操作配合可以实现完整的类型级算术运算。