一、源码
这段代码实现了一个用于统计二进制补码整数位数的系统,支持多种自定义数值类型(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)
-
零成本抽象:编译期确定调用方式,无运行时开销
适用于需要精确控制二进制位数的场景(如硬件寄存器操作、定点数运算等)。