【unitrix数间混合计算】2.23 类型级二进制非负数减法(usub.rs)

一、源码

这段代码是用Rust实现的类型级二进制非负数减法。它使用了类型系统来表示二进制数并在编译时进行计算。

use crate::number::{
    Z0, O, I, Bin,
    BinUnsigned,
    Sub1, SubOne, BinNormalize, IfB0,
};

// ===================== 非负数减法 =====================
pub trait USub<Rhs = Self> {
    type Output;
    fn usub(self, rhs: Rhs) -> Self::Output;
}

pub type USubOut<A, B> = <A as USub<B>>::Output;

impl<U: BinUnsigned> USub<Z0> for U {
    type Output = U;
    #[inline]
    fn usub(self, _: Z0) -> Self::Output { self }
}

impl<Ul: BinUnsigned, Ur: BinUnsigned> USub<Bin<Ur, O>> for Bin<Ul, O>
where
    Ul: USub<Ur>,
    USubOut<Ul, Ur>: BinNormalize<O>,
{
    type Output = IfB0<USubOut<Ul, Ur>>;
    #[inline]
    fn usub(self, _: Bin<Ur, O>) -> Self::Output { Bin::default() }
}

impl<Ul: BinUnsigned, Ur: BinUnsigned> USub<Bin<Ur, O>> for Bin<Ul, I>
where
    Ul: USub<Ur>,
{
    type Output = Bin<USubOut<Ul, Ur>, I>;
    #[inline]
    fn usub(self, _: Bin<Ur, O>) -> Self::Output { Bin::default() }
}

impl<Ul: BinUnsigned, Ur: BinUnsigned> USub<Bin<Ur, I>> for Bin<Ul, O>
where
    Ul: USub<Ur>,
    USubOut<Ul, Ur>: SubOne,
{
    type Output = Bin<Sub1<USubOut<Ul, Ur>>, I>;
    #[inline]
    fn usub(self, _: Bin<Ur, I>) -> Self::Output { Bin::default() }
}

impl<Ul: BinUnsigned, Ur: BinUnsigned> USub<Bin<Ur, I>> for Bin<Ul, I>
where
    Ul: USub<Ur>,
    USubOut<Ul, Ur>: BinNormalize<O>,
{
    type Output = IfB0<USubOut<Ul, Ur>>;
    #[inline]
    fn usub(self, _: Bin<Ur, I>) -> Self::Output { Bin::default() }
}

二、基本概念

  1. 类型级编程:在编译时通过类型系统进行计算,而不是运行时。

  2. 二进制数表示:

  • Z0 表示零

  • O 表示二进制位的0

  • I 表示二进制位的1

  • Bin<U, B> 表示一个二进制数,其中U是更高位的部分,B是最低位(0或1)

三、代码结构

  1. USub trait:

pub trait USub<Rhs = Self> {
    type Output;
    fn usub(self, rhs: Rhs) -> Self::Output;
}
  • 定义了非负数减法trait,Rhs是右操作数类型

  • Output关联类型表示减法结果的类型

  • usub方法执行减法操作

  1. USubOut类型别名:

pub type USubOut<A, B> = <A as USub<B>>::Output;
  • 方便获取减法结果的类型
  1. 具体实现:

a. 任何数减去零:


impl<U: BinUnsigned> USub<Z0> for U {
    type Output = U;
    fn usub(self, _: Z0) -> Self::Output { self }
}
  • 任何数减去零等于它本身

b. 偶数减偶数(…0 - …0):


impl<Ul, Ur> USub<Bin<Ur, O>> for Bin<Ul, O>> where ...
  • 形式:U0 - V0 = (U-V)0

  • 需要高位相减后规范化(去除前导零)

c. 奇数减偶数(…1 - …0):


impl<Ul, Ur> USub<Bin<Ur, O>> for Bin<Ul, I>> where ...
  • 形式:U1 - V0 = (U-V)1

  • 直接高位相减,最低位保持1

d. 偶数减奇数(…0 - …1):


impl<Ul, Ur> USub<Bin<Ur, I>> for Bin<Ul, O>> where ...
  • 形式:U0 - V1 = (U-V-1)1

  • 需要高位相减后再减1,结果最低位为1

e. 奇数减奇数(…1 - …1):


    impl<Ul, Ur> USub<Bin<Ur, I>> for Bin<Ul, I>> where ...
  • 形式:U1 - V1 = (U-V)0

  • 高位相减,最低位变0,需要规范化

四、关键点
  1. 递归计算:通过类型系统递归地处理二进制数的每一位

  2. 边界处理:通过BinNormalize处理前导零的情况

  3. 编译时计算:所有操作都在编译时通过类型系统完成

  4. 类型安全:保证不会出现负数结果(因为是非负数减法)

这种技术常用于需要编译时计算保证的场景,如物理单位计算、密码学或嵌入式系统开发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liuyuan77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值