【PhysUnits】15.6 引入P1后的左移运算(shl.rs)

一、源码

代码实现了Rust的类型级二进制数的左移运算(<<),使用类型系统在编译期进行计算。

rust 复制代码
use super::basic::{Z0, P1, N1, B0, B1, NonZero, NonOne, Unsigned};
use super::sub1::Sub1;
use core::ops::Shl;

// ==================== 左移运算(<<) ====================
// Z0 << U
impl<R: Unsigned> Shl<R> for Z0 {
    type Output = Z0;
    fn shl(self, _: R) -> Self::Output {
        Z0  // 0 << n = 0
    }
}

// P1 << U
impl Shl<Z0> for P1 {// P1 << Z0
    type Output = Self;
    fn shl(self, _: Z0) -> Self::Output {
        self
    }
}

impl Shl<P1> for P1 {// P1 << P1
    type Output = B0<P1>;
    fn shl(self, _: P1) -> Self::Output {
        B0::new()
    }
}

impl<R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for P1
where
    P1: Shl<<R as Sub1>::Output>
{// P1 << 超过1的数
    type Output = B0<<P1 as Shl<R::Output>>::Output>;
    fn shl(self, _: R) -> Self::Output {
        B0::new()
    }
}

// N1 << U
impl Shl<Z0> for N1 {// N1 << Z0
    type Output = Self;
    fn shl(self, _: Z0) -> Self::Output {
        self
    }
}

impl Shl<P1> for N1 {// N1 << P1
    type Output = B0<N1>;
    fn shl(self, _: P1) -> Self::Output {
        B0::new()
    }
}

impl<R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for N1
where
    N1: Shl<<R as Sub1>::Output>
{// P1 << 超过1的数
    type Output = B0<<N1 as Shl<R::Output>>::Output>;
    fn shl(self, _: R) -> Self::Output {
        B0::new()
    }
}

// B0 << U
impl<H: NonZero> Shl<Z0> for B0<H> {// B0 << Z0
    type Output = Self;
    fn shl(self, _: Z0) -> Self::Output {
        self
    }
}

impl<H: NonZero> Shl<P1> for B0<H> {// B0 << P1
    type Output = B0<B0<H>>;
    fn shl(self, _: P1) -> Self::Output {
        B0::new()
    }
}

impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for B0<H>
where
    B0<H>: Shl<<R as Sub1>::Output>
{// B0 << 超过1的数
    type Output = B0<<B0<H> as Shl<R::Output>>::Output>;
    fn shl(self, _: R) -> Self::Output {
        B0::new()
    }
}

// B1 << U
impl<H: NonZero> Shl<Z0> for B1<H> {// B1 << Z0
    type Output = Self;
    fn shl(self, _: Z0) -> Self::Output {
        self
    }
}

impl<H: NonZero> Shl<P1> for B1<H> {// B1 << P1
    type Output = B0<B1<H>>;
    fn shl(self, _: P1) -> Self::Output {
        B0::new()
    }
}

impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for B1<H>
where
    B1<H>: Shl<<R as Sub1>::Output>
{// B1 << 超过1的数
    type Output = B0<<B1<H> as Shl<R::Output>>::Output>;
    fn shl(self, _: R) -> Self::Output {
        B0::new()
    }
}

二、类型和trait引入

rust 复制代码
use super::basic::{Z0, P1, N1, B0, B1, NonZero, NonOne, Unsigned};
use super::sub1::Sub1;
use core::ops::Shl;
  • 从父模块引入基础类型:

    • Z0: 表示0

    • P1: 表示+1

    • N1: 表示-1

    • B0, B1: 二进制位(0和1)

    • 标记trait: NonZero, NonOne, Unsigned

  • Sub1: 减1操作

  • Shl: Rust的左移运算符trait

三、零的左移实现

rust 复制代码
impl<R: Unsigned> Shl<R> for Z0 {
    type Output = Z0;
    fn shl(self, _: R) -> Self::Output {
        Z0  // 0 << n = 0
    }
}
  • 任何数左移0还是0

  • 适用于所有无符号类型R

四、正一(P1)的左移

rust 复制代码
impl Shl<Z0> for P1 { // P1 << 0 = P1
    type Output = Self;
    fn shl(self, _: Z0) -> Self::Output { self }
}

impl Shl<P1> for P1 { // P1 << 1 = B0<P1> (即10,二进制表示)
    type Output = B0<P1>;
    fn shl(self, _: P1) -> Self::Output { B0::new() }
}

impl<R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for P1
where P1: Shl<<R as Sub1>::Output> {
    type Output = B0<<P1 as Shl<R::Output>>::Output>;
    fn shl(self, _: R) -> Self::Output { B0::new() }
}
  • 分三种情况处理:

    • 移0位:保持不变

    • 移1位:变成B0(二进制10)

    • 移多位:递归处理

五、负一(N1)的左移

rust 复制代码
impl Shl<Z0> for N1 { ... }  // 同P1
impl Shl<P1> for N1 { ... }  // 同P1
impl<R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for N1 { ... }  // 同P1
  • 处理逻辑与P1完全相同

六、B0(二进制0)的左移

rust 复制代码
impl<H: NonZero> Shl<Z0> for B0<H> { ... }  // 移0位
impl<H: NonZero> Shl<P1> for B0<H> { ... }  // 移1位
impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for B0<H> { ... }  // 移多位
  • 在二进制数前补0:

    • B0 << 1 = B0<B0>

    • 递归处理多位移动

七、B1(二进制1)的左移

rust 复制代码
impl<H: NonZero> Shl<Z0> for B1<H> { ... }  // 移0位
impl<H: NonZero> Shl<P1> for B1<H> { ... }  // 移1位
impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for B1<H> { ... }  // 移多位
  • 类似B0,但在二进制数低位补0

八、关键点总结

  1. 递归处理:多位移动通过递归减1实现

  2. 类型级计算:所有操作在编译期确定

  3. 二进制表示:

  • B0表示在二进制数H低位加0

  • B1表示在二进制数H低位加1

  1. 特殊值处理:
  • P1表示+1(二进制1)

  • N1表示-1

  • Z0表示0

这种实现方式常用于需要编译期计算的场景,如物理单位系统、矩阵运算等,可以完全消除运行时开销。

相关推荐
FAFU_kyp1 小时前
Rust 所有权(Ownership)学习
开发语言·学习·rust
superman超哥1 小时前
Rust 异步性能的黑盒与透视:Tokio 监控与调优实战
开发语言·后端·rust·编程语言·rust异步性能·rust黑盒与透视·tokio监控与调优
Mr -老鬼1 小时前
Rust 知识图谱 -进阶部分
开发语言·后端·rust
古城小栈1 小时前
Cargo.toml
开发语言·后端·rust
古城小栈2 小时前
Cargo命令工具
开发语言·rust
superman超哥4 小时前
Rust 异步编程的终极考验:Tokio 资源管理与清理
开发语言·rust·编程语言·rust异步编程·tokio资源管理与清理
古城小栈15 小时前
Rust 网络请求库:reqwest
开发语言·网络·rust
WaterRun16 小时前
一个由Rust实现的, 好得多的Windows tree命令: tree++项目简介
rust·github
大厂技术总监下海17 小时前
Rust的“一发逆转弹”:Dioxus 如何用一套代码横扫 Web、桌面、移动与后端?
前端·rust·开源
superman超哥20 小时前
Rust 异步时间管理核心:Tokio 定时器实现机制深度剖析
开发语言·rust·编程语言·rust异步时间管理核心·tokio定时器实现机制·tokio定时器