【unitrix】 7.3 二进制整数 带进位加法实现(int_add.rs)
一、源码
这段代码实现了一个类型级别的带进位加法系统,使用Rust的特质(trait)系统来表示二进制整数的加法操作。
use crate::number::{AddOne, Bit, BitAdd, NonZeroNonMinusOne, NormalizeIf, Null, SubOne, TInt, B, I, O
};// ==================== 带进位加法 ====================
pub trait IntAdd<Lhs, Rhs> {type Output: Default;fn int_add(self, lhs: Lhs, rhs: Rhs) -> Self::Output;
}// ----- 进位参数作为self -----// ----- 零值处理 -----
impl<Int: TInt> IntAdd<B<Null, O>, Int> for O {type Output = Int;#[inline] fn int_add(self, _lhs: B<Null, O>, rhs: Int) -> Self::Output { rhs }
}impl<Int: TInt + AddOne> IntAdd<B<Null, O>, Int> for I {type Output = <Int as AddOne>::Output;#[inline] fn int_add(self, lhs: B<Null, O>, rhs: Int) -> Self::Output { rhs.add_one() }
}// ----- 负一处理 -----
impl<Int: TInt + SubOne> IntAdd<B<Null, I>, Int> for O {type Output = <Int as SubOne>::Output;#[inline] fn int_add(self, lhs: B<Null, I>,rhs: Int) -> Self::Output { rhs.sub_one() }
}impl<Int: TInt> IntAdd<B<Null, I>, Int> for I {type Output = Int;#[inline] fn int_add(self, lhs: B<Null, I>, rhs: Int) -> Self::Output { rhs }
}// ----- 嵌套结构处理 -----
impl<Int: NonZeroNonMinusOne> IntAdd<Int, B<Null, O>> for O {type Output = Int;#[inline] fn int_add(self, lhs: Int, _: B<Null, O>) -> Self::Output { lhs }
}impl<Int: NonZeroNonMinusOne + AddOne> IntAdd<Int, B<Null, O>> for I {type Output = <Int as AddOne>::Output;#[inline] fn int_add(self, lhs: Int, _: B<Null, O>) -> Self::Output { lhs.add_one() }
}impl<Int: NonZeroNonMinusOne + SubOne> IntAdd<Int, B<Null, I>> for O {type Output = <Int as SubOne>::Output;#[inline] fn int_add(self, lhs: Int, _: B<Null, I>) -> Self::Output { lhs.sub_one() }
}impl<Int: NonZeroNonMinusOne> IntAdd<Int, B<Null, I>> for I {type Output = Int;#[inline] fn int_add(self, lhs: Int, _: B<Null, I>) -> Self::Output { lhs }
}// ----- 通用嵌套加法 -----
impl<H1: TInt, L1: Bit, H2: TInt, L2: Bit> IntAdd<B<H1, L1>, B<H2, L2>> for O
whereSelf: BitAdd<L1, L2>,<Self as BitAdd<L1, L2>>::CarryOut: IntAdd<H1, H2>,< <Self as BitAdd<L1, L2>>::CarryOut as IntAdd<H1, H2> >::Output: NormalizeIf<<O as BitAdd<L1, L2>>::Sum>,
{type Output = <<<O as BitAdd<L1, L2>>::CarryOut as IntAdd<H1, H2>>::Outputas NormalizeIf<<O as BitAdd<L1, L2>>::Sum>>::Output;#[inline] fn int_add(self, lhs: B<H1, L1>, rhs: B<H2, L2>) -> Self::Output {let high_sum = self.carry_out(lhs.l, rhs.l).int_add(lhs.h, rhs.h);high_sum.normalize(self.sum(lhs.l, rhs.l))}
}#[cfg(test)]
mod tests {use crate::number:: *;#[test]fn test_zero_addition() {// O + O with carry O = Olet _: <O as IntAdd<Z0, Z0>>::Output = Z0::default();// O + O with carry I = Ilet _: <I as IntAdd<Z0, Z0>>::Output = P1::default();}#[test]fn test_one_addition() {// O + I with carry O = Ilet _: <O as IntAdd<Z0, P1>>::Output = P1::default();// O + I with carry I = I0 (2 in binary)let _: <I as IntAdd<Z0, P1>>::Output = P2::default();}#[test]fn test_minus_one_addition() {// O + (-1) with carry O = (-1)let _: <O as IntAdd<Z0, P1>>::Output = P1::default();// O + (-1) with carry I = Olet _: <I as IntAdd<Z0, P1>>::Output = P2::default();}#[test]fn test_multi_bit_addition() {// 1 + 1 with carry O = I0 (2 in binary)let _: <O as IntAdd<P1, P1>>::Output = P2::default();// 1 + 1 with carry I = I1 (3 in binary)let _: <I as IntAdd<P1, P1>>::Output = P3::default();}#[test]fn test_complex_addition() {// 3 + 2 with carry O = 5let _: <O as IntAdd<P3, P2>>::Output = P5::default();// 3 + 2 with carry I = 6let _: <I as IntAdd<P3, P2>>::Output = P6::default();}#[test]fn test_nested_addition() {// Int + B<Null, O> with carry O = Intlet _: <O as IntAdd<P3, Z0>>::Output = P3::default();// Int + B<Null, O> with carry I = Int + 1let _: <I as IntAdd<P3, Z0>>::Output = <P3 as AddOne>::Output::default();}
}
二、核心结构
- IntAdd trait:
-
定义了带进位加法的接口
-
有3个泛型参数:Lhs(左操作数)、Rhs(右操作数)和self(进位)
-
关联类型Output表示加法结果
-
int_add方法执行实际的加法操作
三、实现分类
- 零值处理
-
当左操作数是B<Null, O>(表示0)时:
-
进位为O(0): 直接返回右操作数
-
进位为I(1): 返回右操作数加1
-
- 负一处理
-
当左操作数是B<Null, I>(表示-1)时:
-
进位为O: 返回右操作数减1
-
进位为I: 直接返回右操作数
-
- 嵌套结构处理
-
当右操作数是B<Null, O>或B<Null, I>时:
- 类似零值和负一处理,但操作数位置相反
- 通用嵌套加法
-
处理两个多位数相加的情况(B<H1, L1> + B<H2, L2>)
-
执行步骤:
-
先对最低位(L1和L2)执行位加法(BitAdd)
-
将产生的进位(CarryOut)用于高位相加(IntAdd<H1, H2>)
-
对结果进行规范化处理(NormalizeIf)
-
四、测试用例
测试覆盖了多种情况:
-
零加法
-
一加法
-
负一加法
-
多位数加法
-
复杂加法
-
嵌套加法
五、类型表示
-
O和I: 表示二进制位0和1
-
B<H, L>: 表示一个二进制数,H是高位部分,L是最低位
-
Null: 表示空/终止
-
Z0: 表示数字0
-
P1, P2等: 表示正整数1,2等
这个实现展示了如何在Rust类型系统中模拟二进制加法运算,利用了特质系统和关联类型来编码数学运算规则。
