【unitrix】 6.9 减一操作(sub_one.rs)
一、源码
这是一个类型级(type-level)的二进制数减一操作的实现,使用Rust的trait系统在编译期完成计算。
use crate::number::{O, I, B, Null, Bit, NormalizeIf};/// 类型级减一操作 trait
///
/// 为二进制数类型实现减一操作,返回新的类型
pub trait SubOne {/// 减一操作的结果类型type Output;/// 执行减一操作fn sub_one(self) -> Self::Output;
}// 基础类型实现 - 处理最简单的情况
impl SubOne for B<Null, O> {type Output = B<Null, I>; // 0 - 1 = -1#[inline]fn sub_one(self) -> Self::Output {B::new()}
}impl SubOne for B<Null, I> {type Output = B<B<Null, I>, O>; // -1 - 1 = -2#[inline]fn sub_one(self) -> Self::Output {B::new()}
}// 递归实现 - 处理通用二进制数
impl<H, L> SubOne for B<B<H, L>, O>
whereB<H, L>: SubOne, // 高位部分需要能减一<B<H, L> as SubOne>::Output: NormalizeIf<I>, // 有进位,如果高位是Z0时忽略O
{type Output = <<B<H, L> as SubOne>::Output as NormalizeIf<I>>::Output;#[inline]fn sub_one(self) -> Self::Output {self.h.sub_one().normalize(I) // 0 - 1 = 1 并借位,如果高位是N1时忽略I}
}impl<H, L> SubOne for B<B<H, L>, I>
whereB<H, L>: NormalizeIf<O>, // 格式检查
{type Output = <B<H, L> as NormalizeIf<O>>::Output;#[inline]fn sub_one(self) -> Self::Output {self.h.normalize(O) // 1 - 1 = 0,无借位,如果高位是Z0时忽略O}
}
二、源码分析
核心设计
- Trait定义:
pub trait SubOne {type Output; // 减一操作的结果类型fn sub_one(self) -> Self::Output;
}
这个trait定义了类型级别的减一操作,关联类型Output表示结果类型。
- 基础实现:
impl SubOne for B<Null, O> { // 0 - 1type Output = B<Null, I>; // = -1 (补码表示)
}impl SubOne for B<Null, I> { // -1 - 1type Output = B<B<Null, I>, O>; // = -2
}
处理了最基本的两种情况:0减1和-1减1。
- 递归实现:
分为两种情况处理通用二进制数:
情况1:最低位是0 (B<B<H,L>,O>)
impl<H,L> SubOne for B<B<H,L>,O> {type Output = <<B<H,L> as SubOne>::Output as NormalizeIf<I>>::Output;fn sub_one(self) -> Self::Output {self.h.sub_one().normalize(I) // 借位处理}
}
-
需要向高位借位
-
使用NormalizeIf处理可能的类型规范化
情况2:最低位是1 (B<B<H,L>,I>)
impl<H,L> SubOne for B<B<H,L>,I> {type Output = <B<H,L> as NormalizeIf<O>>::Output;fn sub_one(self) -> Self::Output {self.h.normalize(O) // 直接置为0,无借位}
}
-
直接翻转最低位
-
使用NormalizeIf处理可能的类型规范化
关键点解析
- 补码表示:
-
B<Null, O>表示0
-
B<Null, I>表示-1
-
B<B<Null,I>,O>表示-2
- 递归处理:
-
通过类型递归实现任意长度的二进制数减一
-
每次处理最低位,根据需要借位
- 规范化处理:
-
使用NormalizeIf trait处理结果类型规范化
-
避免产生前导零等不规范表示
- 编译期计算:
-
所有操作都在类型系统层面完成
-
运行时无开销
示例说明
-
3 (B<B<B<Null, O>,I>, I>)减1:
-
递归处理:B<B<B<Null, O>,I>, I> → B<B<B<Null, O>,I>, O>
-
结果:2 (B<B<B<Null, O>,I>, O>)
-
-
4 (B<B<B<B<Null, O>,I>, O>,O>)减1:
-
最低位是0,需要借位
-
变为:(B<B<B<B<Null, O>,O>, I>,I>) (3)
-
-
0 (B<Null,O>)减1:
- 直接变为B<Null,I> (-1)
设计优势
-
类型安全:所有操作在编译期验证
-
零成本抽象:运行时无额外开销
-
可扩展性:可以组合其他类型级操作
-
精确控制:明确处理各种边界情况
这个实现展示了如何在Rust类型系统中实现复杂的算术运算,是类型级编程的典型范例。