一、源碼
這段代碼實現了一個類型級別的二進制數減法系統,包含標準減法和帶借位減法。
use core::ops::{Neg, Not, Sub};
use super::basic::{Z0, N1, P1, B0, B1, Integer, NonZero};
use super::add1::Add1;
use super::sub1::Sub1;
use super::standardization::{IfB0, IfB1};// ==================== 帶借位減法 Trait ====================
/// 帶借位減法運算
/// Subtraction with borrow operation
///
/// 表示 a - b - 1 的運算 (相當于 a - (b + 1))
/// Represents the operation of a - b - 1 (equivalent to a - (b + 1))
/// 說明:有借位表示有低位數,本位 NonZero
pub trait SubWithBorrow<Rhs> {type Output;
}// ==================== 帶借位減法實現 ====================// ========== 帶借位P1 - NonZero ==========// P1 - I (帶借位) = P1-I-1=-I
impl<I:NonZero + Neg> SubWithBorrow<I> for P1 {type Output = I::Output;
}// ========== 帶借位N1 - NonZero ==========
// N1 - I (帶借位,非0) = !I-1 (即N1+(!I+1)-1)
impl<I: NonZero + Not> SubWithBorrow<I> for N1
where<I as Not>::Output:Sub1,
{type Output = <I::Output as Sub1>::Output;
}// ========== 帶借位B0 - NonZero ==========
// B0 - P1 (帶借位)
impl<H: NonZero + Sub1> SubWithBorrow<P1> for B0<H>
whereH::Output: IfB0,
{type Output = <H::Output as IfB0>::Output;
}// B0 - N1 (帶借位)
impl<H: NonZero> SubWithBorrow<N1> for B0<H>
{type Output = Self;
}// B0 - B0 (帶借位)
impl<H1: NonZero + SubWithBorrow<H2>, H2: NonZero> SubWithBorrow<B0<H2>> for B0<H1>
whereH1::Output: IfB1,
{type Output = <H1::Output as IfB1>::Output;
}// B0 - B1 (帶借位)
impl<H1: NonZero + SubWithBorrow<H2>, H2: NonZero> SubWithBorrow<B1<H2>> for B0<H1>
where<H1 as SubWithBorrow<H2>>::Output: IfB0,
{type Output = <H1::Output as IfB0>::Output;
}// ========== 帶借位B1 - NonZero ==========
// B1 - P1 (帶借位)
impl<H: NonZero + Sub1> SubWithBorrow<P1> for B1<H>
whereH::Output: IfB1,
{type Output = <H::Output as IfB1>::Output;
}// B1 - N1 (帶借位)
impl<H: NonZero> SubWithBorrow<N1> for B1<H>
{type Output = Self;
}// B1 - B0 (帶借位)
impl<H1: NonZero + Sub<H2>, H2: NonZero> SubWithBorrow<B0<H2>> for B1<H1>
where<H1 as Sub<H2>>::Output: IfB0,
{type Output = <H1::Output as IfB0>::Output;
}// B1 - B1 (帶借位)
impl<H1: NonZero + SubWithBorrow<H2>, H2: NonZero> SubWithBorrow<B1<H2>> for B1<H1>
where<H1 as SubWithBorrow<H2>>::Output: IfB1,
{type Output = <H1::Output as IfB1>::Output;
}// ==================== 標準減法實現 (Sub trait) ====================// ========== Z0 - All ==========
// Z0 - I = -I
impl<I: Integer + Neg> Sub<I> for Z0 {type Output = I::Output;fn sub(self, _: I) -> Self::Output {unreachable!("Type-level operation")}
}// ========== P1 - All ==========
// P1 - I = -(I-P1)
impl<I: Integer + Sub1> Sub<I> for P1
where<I as Sub1>::Output: Neg,
{type Output = <I::Output as Neg>::Output;fn sub(self, _: I) -> Self::Output {unreachable!("Type-level operation")}
}// ========== N1 - All ==========
// N1 - I = -(I+P1)
impl<I: Integer + Add1> Sub<I> for N1
where<I as Add1>::Output: Neg,
{type Output = <I::Output as Neg>::Output;fn sub(self, _: I) -> Self::Output {unreachable!("Type-level operation")}
}// ========== B0 - All ==========
// B0 - Z0
impl<H: NonZero> Sub<Z0> for B0<H> {type Output = Self;fn sub(self, _: Z0) -> Self::Output {self}
}// B0 - P1
impl<H: NonZero + Sub1> Sub<P1> for B0<H>
where<H as Sub1>::Output: IfB1,
{type Output = <H::Output as IfB1>::Output;fn sub(self, _: P1) -> Self::Output {unreachable!("Type-level operation")}
}// B0 - N1
impl<H: NonZero + IfB1> Sub<N1> for B0<H>{type Output = H::Output;fn sub(self, _: N1) -> Self::Output {unreachable!("Type-level operation")}
}// B0 - B0
impl<H1: NonZero + Sub<H2>, H2: NonZero> Sub<B0<H2>> for B0<H1>
where<H1 as Sub<H2>>::Output: IfB0,
{type Output = <H1::Output as IfB0>::Output;fn sub(self, _: B0<H2>) -> Self::Output {unreachable!("Type-level operation")}
}// B0 - B1 (需要借位)
impl<H1: NonZero + SubWithBorrow<H2>, H2: NonZero> Sub<B1<H2>> for B0<H1>
where<H1 as SubWithBorrow<H2>>::Output: IfB1,
{type Output = <H1::Output as IfB1>::Output;fn sub(self, _: B1<H2>) -> Self::Output {unreachable!("Type-level operation")}
}// ========== B1 - All ==========
// B1-Z0
impl<H: NonZero> Sub<Z0> for B1<H> {type Output = Self;fn sub(self, _: Z0) -> Self::Output {self}
}// B1 - P1
impl<H: NonZero + IfB0> Sub<P1> for B1<H> {type Output = H::Output;fn sub(self, _: P1) -> Self::Output {unreachable!("Type-level operation")}
}// B1 - N1
impl<H: NonZero + Add1> Sub<N1> for B1<H>
where <H as Add1>::Output: IfB0,
{type Output = <H::Output as IfB0>::Output;fn sub(self, _: N1) -> Self::Output {unreachable!("Type-level operation")}
}// B1 - B0
impl<H1: NonZero + Sub<H2>, H2: NonZero> Sub<B0<H2>> for B1<H1>
where<H1 as Sub<H2>>::Output: IfB1,
{type Output = <H1::Output as IfB1>::Output;fn sub(self, _: B0<H2>) -> Self::Output {unreachable!("Type-level operation")}
}// B1 - B1
impl<H1: NonZero + Sub<H2>, H2: NonZero> Sub<B1<H2>> for B1<H1>
where<H1 as Sub<H2>>::Output: IfB0,
{type Output = <H1::Output as IfB0>::Output;fn sub(self, _: B1<H2>) -> Self::Output {unreachable!("Type-level operation")}
}
二、核心設計
類型系統基礎
use super::basic::{Z0, N1, P1, B0, B1}; // 基礎類型:
// Z0 = 零, N1 = -1, P1 = +1
// B0<H> = 二進制數低位為0 (如 10)
// B1<H> = 二進制數低位為1 (如 11)
關鍵Trait定義
pub trait SubWithBorrow<Rhs> { // 帶借位減法(a-b-1)type Output;
}impl core::ops::Sub<Rhs> { // 標準減法(a-b)type Output;
}
三、帶借位減法實現
特殊值處理
// P1 - I (帶借位) = -I
impl<I: NonZero + Neg> SubWithBorrow<I> for P1 {type Output = I::Output; // 直接取負
}// N1 - I (帶借位) = !I - 1
impl<I: NonZero + Not> SubWithBorrow<I> for N1
whereI::Output: Sub1 // 按位取反后減1
{type Output = <I::Output as Sub1>::Output;
}
二進制數處理
// B0 - B1 的遞歸借位處理
impl<H1, H2> SubWithBorrow<B1<H2>> for B0<H1>
whereH1: SubWithBorrow<H2>, // 高位遞歸H1::Output: IfB1 // 結果標準化
{type Output = B1<H1::Output>; // 借位后變B1
}// B1 - B1 的遞歸處理
impl<H1, H2> SubWithBorrow<B1<H2>> for B1<H1>
whereH1: Sub<H2>, // 普通減法H1::Output: IfB0 // 結果標準化
{type Output = B0<H1::Output>;
}
四、標準減法實現
運算符重載模式
impl<I> Sub<I> for Z0 { // 零減任何數type Output = I::Neg; // 直接取負fn sub(self, _: I) -> Self::Output { unreachable!() }
}impl<H> Sub<Z0> for B0<H> { // 二進制數減零type Output = Self;fn sub(self, _: Z0) -> Self { self }
}
遞歸減法
// B1 - B0 的遞歸處理
impl<H1, H2> Sub<B0<H2>> for B1<H1>
whereH1: Sub<H2>, // 高位相減H1::Output: IfB1 // 結果標準化
{type Output = B1<H1::Output>;
}
五、標準化處理
通過 IfB0/IfB1 trait 處理特殊情況:
B0<Z0> => Z0 // 消除前導零
B1<N1> => N1 // 二進制補碼優化
B1<Z0> => P1 // 單比特正數
六、設計亮點
- 雙重減法系統:
-
標準減法:a - b
-
帶借位減法:a - b - 1(處理低位借位)
- 完備的數學規則:
// 負數減法轉換為加法
impl<I: Add1> Sub<I> for N1 {type Output = Neg<I::Add1>;
}
- 遞歸類型處理:
// 處理二進制數的遞歸減法
impl<H1, H2> Sub<B1<H2>> for B1<H1> {type Output = B0<H1::Sub<H2>>;
}
七、典型運算示例
type A = B1<B0<Z0>>; // 二進制10(2)
type B = B1<Z0>; // 二進制1(1)
type Diff = <A as Sub<B>>::Output; // 得到P1 (1)// 帶借位減法示例
type C = B0<B1<Z0>>; // 二進制01(1)
type D = B1<Z0>; // 二進制1(1)
type BorrowDiff = <C as SubWithBorrow<D>>::Output; // 得到N1 (-1)
八、異常處理機制
所有運行時方法都標記為:
fn sub(self, _: Rhs) -> Self::Output {unreachable!("Type-level operation") // 確保不會實際執行
}
這個系統通過編譯期類型計算實現了:
-
任意長度二進制數減法
-
自動借位處理
-
結果標準化
-
零運行時開銷
適用于需要編譯期數值驗證的場景,如協議編解碼等。