【typenum】 24 去除尾部零的特性(private.rs片段)
一、源码
这段代码实现了一个去除尾部零的特性(trait),专门用于处理倒序存储的无符号整数。
- 定义及别名
/// Gets rid of all zeros until it hits a one.
// ONLY IMPLEMENT FOR INVERTED NUMBERS!
pub trait TrimTrailingZeros {type Output;fn trim_trailing_zeros(self) -> Self::Output;
}
pub type TrimTrailingZerosOut<A> = <A as TrimTrailingZeros>::Output;
- 实现
impl TrimTrailingZeros for InvertedUTerm {type Output = InvertedUTerm;#[inline]fn trim_trailing_zeros(self) -> Self::Output {InvertedUTerm}
}impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B1> {type Output = Self;#[inline]fn trim_trailing_zeros(self) -> Self::Output {self}
}impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0>
whereIU: TrimTrailingZeros,
{type Output = <IU as TrimTrailingZeros>::Output;#[inline]fn trim_trailing_zeros(self) -> Self::Output {self.msb.trim_trailing_zeros()}
}
二、核心概念
TrimTrailingZeros 特性用于移除二进制数末尾的零,直到遇到第一个1为止。
示例:
-
10100(倒序存储)→ 去除尾部零 → 101
-
100 → 1
-
000 → 0(完全去除)
三、特性定义
pub trait TrimTrailingZeros {type Output; // 关联类型:修剪后的输出类型fn trim_trailing_zeros(self) -> Self::Output;
}
四、三种实现情况
- 基础情况:空项(数字0)
impl TrimTrailingZeros for InvertedUTerm {type Output = InvertedUTerm; // 0修剪后还是0fn trim_trailing_zeros(self) -> Self::Output {InvertedUTerm // 直接返回空项}
}
处理数字0的情况,没有零需要去除。
2. 遇到1:停止修剪
impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B1> {type Output = Self; // 输出类型不变fn trim_trailing_zeros(self) -> Self::Output {self // 直接返回自身,停止修剪}
}
当遇到最低位是1时,说明已经到达有效数字的末尾,停止修剪。
3. 遇到0:继续递归修剪
impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0>
whereIU: TrimTrailingZeros, // 要求内部类型也能修剪
{type Output = <IU as TrimTrailingZeros>::Output; // 使用内部的输出类型fn trim_trailing_zeros(self) -> Self::Output {self.msb.trim_trailing_zeros() // 递归修剪更高位}
}
当最低位是0时,丢弃这个零,继续修剪更高位。
五、工作流程示例
假设有倒序数字 100(传统二进制 001 = 1):
// 类型:InvertedUInt<InvertedUInt<InvertedUInt<InvertedUTerm, B1>, B0>, B0>
// 修剪过程:
1. 最外层是B0 → 丢弃,递归修剪内部
2. 内部是B0 → 丢弃,递归修剪内部
3. 内部是B1 → 停止修剪,返回自身
// 最终结果:InvertedUInt<InvertedUTerm, B1>(即数字1)
六、设计特点
-
递归处理:通过类型递归逐步去除尾部零
-
编译时操作:所有修剪在编译期完成
-
类型级编程:使用关联类型保持类型安全
-
条件实现:使用where子句约束类型能力
这种设计常用于需要精确控制数值表示的场景,如二进制协议处理或数值优化算法。