一、源碼
這段代碼實現了一個用于統計二進制補碼整數位數的系統,支持多種自定義數值類型(Z0、P1、N1、B0、B1)。
use core::mem::size_of;
use crate::number::{Z0, P1, N1, B0, B1, Var};/// 統計二進制位數的 trait
pub trait BitLength {fn bit_length(self) -> usize;
}// 基本類型實現
impl BitLength for Z0 {fn bit_length(self) -> usize { 0 } // Z0 不算位數
}impl BitLength for P1 {fn bit_length(self) -> usize { 1 } // P1 = +1 (1位)
}impl BitLength for N1 {fn bit_length(self) -> usize { 1 } // N1 = -1 (1位)
}/// B0<H> 的位數 = 1 (當前位) + H 的位數
impl<H> BitLength for B0<H>
whereH: BitLength,
{fn bit_length(self) -> usize {1 + self.0.bit_length() // 遞歸調用(運行時,不會觸發編譯器遞歸檢查)}
}/// B1<H> 的位數 = 1 (當前位) + H 的位數
impl<H> BitLength for B1<H>
whereH: BitLength,
{fn bit_length(self) -> usize {1 + self.0.bit_length() // 遞歸調用(運行時)}
}/// 檢查位數是否超過 Var<T> 的 T 的位數限制
pub fn check_bit_length<T>(value: impl BitLength) -> bool
whereT: PrimitiveInt, // 假設 Primitive 是整數類型(如 i32, i64)
{let max_bits = size_of::<T>() * 8; // 如 i32 = 32 位value.bit_length() <= max_bits
}
二、核心設計
- 類型定義
-
Z0:表示數值0(0位)
-
P1:表示+1(1位)
-
N1:表示-1(1位)
-
B0/B1:遞歸結構,表示二進制補碼的高位部分
- 關鍵Trait
pub trait BitLength {fn bit_length(self) -> usize; // 按值消費self
}
-
所有數值類型必須實現該trait來計算自身位數
-
按值傳遞(self而非&self)要求類型必須實現Copy或調用時轉移所有權
三、位數計算規則
- 基本類型
類型 | 位數 | 解釋 |
---|---|---|
Z0 | 0 | 數值0不占有效位 |
P1 | 1 | 二進制1(+1) |
N1 | 1 | 二進制1(-1的補碼) |
- 復合類型
- B0<H>:當前位0 + 高位位數
1 + self.0.bit_length()
- B1<H>:當前位1 + 高位位數
1 + self.0.bit_length()
四、邊界檢查函數
pub fn check_bit_length<T>(value: impl BitLength) -> bool
whereT: PrimitiveInt,
{let max_bits = size_of::<T>() * 8; // 計算T類型的位數容量value.bit_length() <= max_bits // 比較實際位數
}
-
功能:檢查數值的位數是否不超過Var中T的位數限制
-
示例:
let num = B0(B1(P1)); // 二進制01(十進制+1,2位)assert!(check_bit_length::<i32>(num)); // 檢查是否適合i32(32位)
五、關鍵實現細節
- 遞歸解析
-
B0<B1>的解析過程:
+B0.bit_length() → 1 + B1.bit_length()
-
B1.bit_length() → 1 + P1.bit_length()
-
P1.bit_length() → 1
-
最終結果:1 + 1 + 1 = 3位
-
- 所有權處理
-
所有方法使用self而非&self,意味著:
-
類型應實現Copy(如#[derive(Copy, Clone)])
-
或調用時轉移所有權(適合一次性使用的場景)
-
- 泛型約束
impl<H> BitLength for B0<H> where H: BitLength
- 確保嵌套類型H也必須實現BitLength
六、使用示例
// 定義結構體(需實現Copy)
#[derive(Copy, Clone)]
struct P1;// 計算B0(B1(P1))的位數
let num = B0(B1(P1));
assert_eq!(num.bit_length(), 3);// 檢查是否適合i8
assert!(check_bit_length::<i8>(num)); // 3 <= 8
七、潛在問題與改進
- 遞歸深度
-
問題:極深嵌套(如B0<B0<B0<…>>>)可能導致棧溢出
-
改進:改為迭代實現(如用while let循環遍歷結構)
- 類型限制
-
要求:所有類型必須實現Copy或允許所有權轉移
-
替代方案:改用&self避免所有權問題
fn bit_length(&self) -> usize;
八、總結
該代碼實現了一個類型安全的二進制位數統計系統:
-
通過trait統一接口:所有數值類型實現BitLength
-
遞歸計算位數:B0/B1遞歸組合子類型位數
-
邊界檢查:驗證數值是否適合目標整數類型(如i32)
-
零成本抽象:編譯期確定調用方式,無運行時開銷
適用于需要精確控制二進制位數的場景(如硬件寄存器操作、定點數運算等)。