【PhysUnits】15.7 引入P1后的加法运算(add.rs)
一、源码
这段代码实现了一个类型级别的二进制数加法系统,支持基本加法和带进位加法运算。
// 类型级别二进制数加法实现
/// Type-level binary number addition implementation
///
/// 本模块提供类型级别的二进制数加法运算,包括:
/// This module provides type-level binary number addition operations, including:
/// - 基本加法 (Basic addition)
/// - 带进位加法 (Addition with carry)
/// - 结果标准化处理 (Result standardization)
use core::ops::Add;
use super::basic::{B0, B1, Z0, P1, N1, Integer, NonZero};
use super::add1::Add1;
use super::sub1::Sub1;
use super::standardization::{IfB0,IfB1};// ==================== 带进位加法 Trait ====================
// ==================== Addition With Carry Trait ====================/// 带进位加法运算
/// Addition with carry operation
///
/// 表示 a + b + 1 的运算
/// Represents the operation of a + b + 1
/// 说明:有进位,说明有低位数,目前B1<Z0>已经被P1替换,本位NonZeropub trait AddWithCarry<Rhs> {// NonZerotype Output;
}// ========== 带进位P1 + NonZero ==========
// 带进位 P1 + All
impl<I:NonZero+ Add<B0<P1>>> AddWithCarry<I> for P1
{type Output = I::Output;
}// ========== 带进位N1 + NonZero ==========
impl<I:NonZero> AddWithCarry<I> for N1 {type Output = I;
}// ========== 带进位B0 + NonZero ==========
// B0 + P1
impl<H: NonZero + Add1> AddWithCarry<P1> for B0<H>
where<H as Add1>::Output:IfB0
{//避免B1<N1>,需要特化type Output = <H::Output as IfB0>::Output;
}// B0 + N1
impl<H: NonZero> AddWithCarry<N1> for B0<H>{type Output = Self;
}// B0 + B0
impl<H1: NonZero + IfB1,H2: NonZero> AddWithCarry<B0<H2>> for B0<H1>{type Output = H1::Output;
}// B0 + B1
impl<H1: NonZero + AddWithCarry<H2>,H2: NonZero> AddWithCarry<B1<H2>> for B0<H1>
where<H1 as AddWithCarry<H2>>::Output:IfB0
{type Output = <H1::Output as IfB0>::Output;
}// ========== 带进位B1 + NonZero ==========// B1 + P1
impl<H: NonZero + Add1> AddWithCarry<P1> for B1<H>
where<H as Add1>::Output:IfB1,
{type Output = <H::Output as IfB1>::Output;
}// B1 + N1
impl<H: NonZero + Add1> AddWithCarry<N1> for B1<H>{// 不变type Output = Self;
}// B1 + B0
impl<H1: NonZero + AddWithCarry<H2>,H2: NonZero> AddWithCarry<B0<H2>> for B1<H1>
where<H1 as AddWithCarry<H2>>::Output:IfB0
{type Output = <H1::Output as IfB0>::Output;
}// B1 + B1
impl<H1: NonZero + AddWithCarry<H2>,H2: NonZero> AddWithCarry<B1<H2>> for B1<H1>
where<H1 as AddWithCarry<H2>>::Output:IfB1
{type Output = <H1::Output as IfB1>::Output;
}// ==================== 运算符重载 ====================// ==================== Z0 + All ====================
// Z0 + 整数
impl<I: Integer> Add<I> for Z0 {type Output = I;#[inline(always)]fn add(self, rhs: I) -> Self::Output {rhs}
}// ==================== P1 + All ====================
impl<I: Integer + Add1> Add<I> for P1 {type Output = I::Output;#[inline(always)]fn add(self, _rhs: I) -> Self::Output {unreachable!("Type-level operation")}
}// ==================== N1 + All ====================
impl<I: Integer + Sub1> Add<I> for N1 {type Output = I::Output;#[inline(always)]fn add(self, _rhs: I) -> Self::Output {unreachable!("Type-level operation")}
}// ==================== B0 + All ====================
// B0 + Z0
impl<H: NonZero> Add<Z0> for B0<H> {type Output = Self;#[inline(always)]fn add(self, _rhs: Z0) -> Self::Output {self}
}// B0 + P1
impl<H: NonZero + IfB1> Add<P1> for B0<H> {type Output = H::Output;#[inline(always)]fn add(self, _rhs: P1) -> Self::Output {unreachable!("Type-level operation")}
}// B0 + N1
impl<H: NonZero + Sub1> Add<N1> for B0<H>
where<H as Sub1>::Output: IfB1,
{type Output = <H::Output as IfB1>::Output;#[inline(always)]fn add(self, _rhs: N1) -> Self::Output {unreachable!("Type-level operation")}
}// B0 + B0
impl<H1: NonZero + Add<H2> + , H2: NonZero> Add<B0<H2>> for B0<H1>
where<H1 as Add<H2>>::Output: IfB0,
{type Output = <H1::Output as IfB0>::Output;#[inline(always)]fn add(self, _rhs: B0<H2>) -> Self::Output {unreachable!("Type-level operation")}
}// B0 + B1
impl<H1: NonZero + Add<H2>, H2: NonZero> Add<B1<H2>> for B0<H1>
where<H1 as Add<H2>>::Output: IfB1,
{type Output = <H1::Output as IfB1>::Output;#[inline(always)]fn add(self, _rhs: B1<H2>) -> Self::Output {unreachable!("Type-level operation")}
}// ==================== B1 + All ====================
// B1 + Z0
impl<H: NonZero> Add<Z0> for B1<H> {type Output = Self;#[inline(always)]fn add(self, _rhs: Z0) -> Self::Output {self}
}// B1 + P1
impl<H: NonZero + Add1> Add<P1> for B1<H>
where<H as Add1>::Output: IfB0,
{type Output = <H::Output as IfB0>::Output;#[inline(always)]fn add(self, _rhs: P1) -> Self::Output {unreachable!("Type-level operation")}
}// B1 + N1
impl<H: NonZero + IfB0> Add<N1> for B1<H>{type Output = H::Output;#[inline(always)]fn add(self, _rhs: N1) -> Self::Output {unreachable!("Type-level operation")}
}// B1 + B0
impl<H1: NonZero + Add<H2> + , H2: NonZero> Add<B0<H2>> for B1<H1>
where<H1 as Add<H2>>::Output: IfB1,
{type Output = <H1::Output as IfB1>::Output;#[inline(always)]fn add(self, _rhs: B0<H2>) -> Self::Output {unreachable!("Type-level operation")}
}// B1 + B1
impl<H1: NonZero + AddWithCarry<H2>, H2: NonZero> Add<B1<H2>> for B1<H1>
where<H1 as AddWithCarry<H2>>::Output: IfB0,
{type Output = <H1::Output as IfB0>::Output;#[inline(always)]fn add(self, _rhs: B1<H2>) -> Self::Output {unreachable!("Type-level operation")}
}
二、核心设计
类型系统架构
use super::basic::{B0, B1, Z0, P1, N1}; // 基础类型:
// B0<H> = 二进制数末尾加0 (如 10)
// B1<H> = 二进制数末尾加1 (如 11)
// Z0 = 零, P1 = +1, N1 = -1
关键Trait
pub trait AddWithCarry<Rhs> { // 带进位加法(a+b+1)type Output;
}impl core::ops::Add<Rhs> { // 普通加法(a+b)type Output;
}
三、带进位加法实现
特殊值处理
// P1 + I = I的Add结果(进位传递)
impl<I: NonZero + Add<B0<P1>>> AddWithCarry<I> for P1 {type Output = I::Output;
}// N1 + I = I自身(负一抵消进位)
impl<I: NonZero> AddWithCarry<I> for N1 {type Output = I;
}
二进制数处理
// B0 + B1 的递归处理
impl<H1, H2> AddWithCarry<B1<H2>> for B0<H1>
where H1: AddWithCarry<H2>,H1::Output: IfB0 // 标准化输出
{type Output = <H1::Output as IfB0>::Output;
}// B1 + B1 产生进位
impl<H1, H2> AddWithCarry<B1<H2>> for B1<H1>
whereH1: AddWithCarry<H2>,H1::Output: IfB0 // 进位后变B0
{type Output = B0<H1::Output>;
}
四、普通加法实现
运算符重载模式
impl<I> Add<I> for Z0 { // 零加任何数type Output = I;fn add(self, _: I) -> I { unreachable!() }
}impl<H> Add<Z0> for B0<H> { // 二进制数加零type Output = Self;fn add(self, _: Z0) -> Self { self }
}
递归加法
// B0 + B0 的递归处理
impl<H1, H2> Add<B0<H2>> for B0<H1>
whereH1: Add<H2>,H1::Output: IfB0 // 标准化
{type Output = <H1::Output as IfB0>::Output;
}
五、标准化处理
通过 IfB0/IfB1 trait 处理特殊情况:
B0<Z0> => Z0 // 消除前导零
B1<N1> => N1 // 二进制补码优化
B1<Z0> => P1 // 单比特正数
六、设计亮点
-
递归类型计算:通过泛型递归处理任意长度的二进制数
-
零成本抽象:所有计算在编译期完成
-
完备的特殊情况处理:覆盖所有可能的输入组合
-
类型安全:通过 trait bound 保证运算合法性
七、使用示例
type A = B0<B1<Z0>>; // 二进制10(2)
type B = B1<Z0>; // 二进制1(1)
type Sum = <A as Add<B>>::Output; // 得到P1 (标准化表示)
这段代码典型应用于需要编译期数值计算的场景,如:
-
嵌入式系统资源管理
-
类型安全的状态机实现
通过这种类型级编程,可以在编译期捕获数值运算错误,保证运行时安全性。