一、源码
这段代码是用Rust实现的类型级二进制非负数减法。它使用了类型系统来表示二进制数并在编译时进行计算。
use crate::number::{
Z0, O, I, Bin,
BinUnsigned,
Sub1, SubOne, BinNormalize, IfB0,
};
// ===================== 非负数减法 =====================
pub trait USub<Rhs = Self> {
type Output;
fn usub(self, rhs: Rhs) -> Self::Output;
}
pub type USubOut<A, B> = <A as USub<B>>::Output;
impl<U: BinUnsigned> USub<Z0> for U {
type Output = U;
#[inline]
fn usub(self, _: Z0) -> Self::Output { self }
}
impl<Ul: BinUnsigned, Ur: BinUnsigned> USub<Bin<Ur, O>> for Bin<Ul, O>
where
Ul: USub<Ur>,
USubOut<Ul, Ur>: BinNormalize<O>,
{
type Output = IfB0<USubOut<Ul, Ur>>;
#[inline]
fn usub(self, _: Bin<Ur, O>) -> Self::Output { Bin::default() }
}
impl<Ul: BinUnsigned, Ur: BinUnsigned> USub<Bin<Ur, O>> for Bin<Ul, I>
where
Ul: USub<Ur>,
{
type Output = Bin<USubOut<Ul, Ur>, I>;
#[inline]
fn usub(self, _: Bin<Ur, O>) -> Self::Output { Bin::default() }
}
impl<Ul: BinUnsigned, Ur: BinUnsigned> USub<Bin<Ur, I>> for Bin<Ul, O>
where
Ul: USub<Ur>,
USubOut<Ul, Ur>: SubOne,
{
type Output = Bin<Sub1<USubOut<Ul, Ur>>, I>;
#[inline]
fn usub(self, _: Bin<Ur, I>) -> Self::Output { Bin::default() }
}
impl<Ul: BinUnsigned, Ur: BinUnsigned> USub<Bin<Ur, I>> for Bin<Ul, I>
where
Ul: USub<Ur>,
USubOut<Ul, Ur>: BinNormalize<O>,
{
type Output = IfB0<USubOut<Ul, Ur>>;
#[inline]
fn usub(self, _: Bin<Ur, I>) -> Self::Output { Bin::default() }
}
二、基本概念
-
类型级编程:在编译时通过类型系统进行计算,而不是运行时。
-
二进制数表示:
-
Z0 表示零
-
O 表示二进制位的0
-
I 表示二进制位的1
-
Bin<U, B> 表示一个二进制数,其中U是更高位的部分,B是最低位(0或1)
三、代码结构
- USub trait:
pub trait USub<Rhs = Self> {
type Output;
fn usub(self, rhs: Rhs) -> Self::Output;
}
-
定义了非负数减法trait,Rhs是右操作数类型
-
Output关联类型表示减法结果的类型
-
usub方法执行减法操作
- USubOut类型别名:
pub type USubOut<A, B> = <A as USub<B>>::Output;
- 方便获取减法结果的类型
- 具体实现:
a. 任何数减去零:
impl<U: BinUnsigned> USub<Z0> for U {
type Output = U;
fn usub(self, _: Z0) -> Self::Output { self }
}
- 任何数减去零等于它本身
b. 偶数减偶数(…0 - …0):
impl<Ul, Ur> USub<Bin<Ur, O>> for Bin<Ul, O>> where ...
-
形式:U0 - V0 = (U-V)0
-
需要高位相减后规范化(去除前导零)
c. 奇数减偶数(…1 - …0):
impl<Ul, Ur> USub<Bin<Ur, O>> for Bin<Ul, I>> where ...
-
形式:U1 - V0 = (U-V)1
-
直接高位相减,最低位保持1
d. 偶数减奇数(…0 - …1):
impl<Ul, Ur> USub<Bin<Ur, I>> for Bin<Ul, O>> where ...
-
形式:U0 - V1 = (U-V-1)1
-
需要高位相减后再减1,结果最低位为1
e. 奇数减奇数(…1 - …1):
impl<Ul, Ur> USub<Bin<Ur, I>> for Bin<Ul, I>> where ...
-
形式:U1 - V1 = (U-V)0
-
高位相减,最低位变0,需要规范化
四、关键点
-
递归计算:通过类型系统递归地处理二进制数的每一位
-
边界处理:通过BinNormalize处理前导零的情况
-
编译时计算:所有操作都在编译时通过类型系统完成
-
类型安全:保证不会出现负数结果(因为是非负数减法)
这种技术常用于需要编译时计算保证的场景,如物理单位计算、密码学或嵌入式系统开发。