当前位置: 首页 > news >正文

【PhysUnits】15.9 引入P1后的右移运算(shr.rs)

一、源码

这段代码是用Rust实现的类型级右移运算(>>),属于类型级编程的范畴。它通过类型系统来表示和操作二进制数,并在编译期完成计算。

use super::basic::{Z0, P1, N1, B0, B1, NonZero, NonOne, Unsigned};
use super::sub1::Sub1;
use core::ops::Shr;// ==================== Right Shift Operation (>>) ====================
// ==================== 右移运算(>>) ====================// Z0 >> U
// Zero right shifted by any unsigned number is still zero
// 零右移任何无符号数仍然是零
impl<R: Unsigned> Shr<R> for Z0 {type Output = Z0;fn shr(self, _: R) -> Self::Output {Z0  // 0 >> n = 0}
}// P1 >> U
// Positive one right shifted by zero is itself
// 正一右移零位是其本身
impl Shr<Z0> for P1 {type Output = Self;fn shr(self, _: Z0) -> Self::Output {self}
}// Positive one right shifted by any non-zero unsigned number becomes zero
// 正一右移任何非零无符号数变为零
impl<R: Unsigned + NonZero> Shr<R> for P1 {type Output = Z0;fn shr(self, _: R) -> Self::Output {Z0::new()}
}// N1 >> U
// Negative one right shifted by any unsigned number remains negative one
// (due to sign extension in two's complement)
// 负一右移任何无符号数仍然是负一(由于二进制补码中的符号扩展)
impl<R: Unsigned> Shr<R> for N1 {type Output = Self;fn shr(self, _: R) -> Self::Output {self}
}// B0 >> U
// Binary number ending with 0 right shifted by zero is itself
// 以0结尾的二进制数右移零位是其本身
impl<H: NonZero> Shr<Z0> for B0<H> {type Output = Self;fn shr(self, _: Z0) -> Self::Output {self}
}// Binary number ending with 0 right shifted by one becomes its head
// 以0结尾的二进制数右移一位变为其头部
impl<H: NonZero> Shr<P1> for B0<H> {type Output = H;fn shr(self, _: P1) -> Self::Output {H::default()}
}// Binary number ending with 0 right shifted by more than one
// Recursively shifts right by one until the shift amount is zero
// 以0结尾的二进制数右移多于一位
// 递归地右移一位直到移位量为零
impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shr<R> for B0<H>
whereH: Shr<<R as Sub1>::Output>
{type Output = <H as Shr<R::Output>>::Output;fn shr(self, r: R) -> Self::Output {(self>>P1)>>r.sub1()}
}// B1 >> U
// Binary number ending with 1 right shifted by zero is itself
// 以1结尾的二进制数右移零位是其本身
impl<H: NonZero> Shr<Z0> for B1<H> {type Output = Self;fn shr(self, _: Z0) -> Self::Output {self}
}// Binary number ending with 1 right shifted by one becomes its head
// 以1结尾的二进制数右移一位变为其头部
impl<H: NonZero> Shr<P1> for B1<H> {type Output = H;fn shr(self, _: P1) -> Self::Output {H::default()}
}// Binary number ending with 1 right shifted by more than one
// Recursively shifts right by one until the shift amount is zero,
// and maintains the sign bit (B0 prefix)
// 以1结尾的二进制数右移多于一位
// 递归地右移一位直到移位量为零,并保持符号位(B0前缀)
impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shr<R> for B1<H>
whereH: Shr<<R as Sub1>::Output>
{type Output = <H as Shr<R::Output>>::Output;fn shr(self, r: R) -> Self::Output {(self>>P1)>>(r.sub1())}
}// Test cases
#[cfg(test)]
mod tests {use super::*;#[test]fn test_shr() {// Test Z0let _: Z0 = Z0 >> Z0;let _: Z0 = Z0 >> P1;// Test P1let _: P1 = P1 >> Z0;let _: Z0 = P1 >> P1;// Test N1let _: N1 = N1 >> Z0;let _: N1 = N1 >> P1;// Test B0let b0: B0<P1> = B0::new();let _: B0<P1> = b0 >> Z0;let _: P1 = b0 >> P1;// Test B1let b1: B1<P1> = B1::new();let _: B1<P1> = b1 >> Z0;let _: P1 = b1 >> P1;}
}

二、基本概念

  1. 类型定义:
  • Z0:表示数字0

  • P1:表示+1

  • N1:表示-1

  • B0:表示以0结尾的二进制数(如B0表示二进制10,即十进制2)

  • B1:表示以1结尾的二进制数(如B1表示二进制11,即十进制3)

  • NonZero、NonOne、Unsigned:这些是标记trait,用于约束类型参数

  1. 核心trait:
  • Shr:Rust的右移运算符trait,这里为不同类型实现了该trait

三、实现逻辑

  1. Z0(零)的右移:
  • 任何数右移0位保持不变

  • 0右移任何位数仍然是0

  1. P1(+1)的右移:
  • 右移0位:保持不变

  • 右移非零位:变为0(因为正数的右移会补0)

  1. N1(-1)的右移:
  • 右移任何位数都保持不变(因为负数的右移在补码表示中会进行符号扩展)
  1. B0(以0结尾的二进制数)的右移:
  • 右移0位:保持不变

  • 右移1位:去掉最后一位0,变成头部H

  • 右移多位:递归地右移1位直到完成

  1. B1(以1结尾的二进制数)的右移:
  • 类似B0,但会保持符号位
递归实现

对于多位右移操作,代码使用了递归的方式:

impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shr<R> for B0<H>
whereH: Shr<<R as Sub1>::Output>
{type Output = <H as Shr<R::Output>>::Output;fn shr(self, r: R) -> Self::Output {(self>>P1)>>r.sub1()}
}

这里的意思是:要计算B0 >> R,先右移1位变成H,然后对剩下的R-1位继续右移。

测试用例

测试了各种情况:

  • 零的右移

  • +1的右移

  • -1的右移

  • 以0结尾的二进制数的右移

  • 以1结尾的二进制数的右移

四、总结

这段代码展示了如何利用Rust的类型系统在编译期完成右移运算。通过为不同类型实现Shr trait,并使用递归类型计算,实现了类型安全的右移操作。这种技术常用于嵌入式开发等需要编译期计算的场景。

http://www.lqws.cn/news/75889.html

相关文章:

  • Vue-4-前端框架Vue基础入门之Vue的常用操作
  • 二叉树的构建与逆构建/二叉查找树与替罪羊树
  • 安全态势感知中的告警误报思考
  • SDU棋界精灵——实现硬件程序ESP32的FreeRTOS任务
  • day44 python 训练CNN网络并使用Grad-CAM可视化
  • NTP库详解
  • React Hooks 与异步数据管理
  • react实现markdown文件预览
  • A. We Need the Zero
  • NX869NX874美光固态颗粒NX877NX883
  • Vortex GPGPU的github流程跑通与功能模块波形探索(四)
  • FFmpeg移植教程(linux平台)
  • RSCUcaller
  • 12.1 GUI 事件处理
  • 《 C++ 点滴漫谈: 四十 》文本的艺术:C++ 正则表达式的高效应用之道
  • 前端高频面试题2:JavaScript/TypeScript
  • 迈向分布式智能:解析MCP到A2A的通信范式迁移
  • 第十二节:第四部分:集合框架:List系列集合:LinkedList集合的底层原理、特有方法、栈、队列
  • 【华为云Astro Zero】组装设备管理页面开发(图形拖拽 + 脚本绑定)
  • Ubuntu上进行VS Code的配置
  • STM32G4 电机外设篇(四)DAC输出电流波形 + CAN通讯
  • 16QAM在瑞利信道下的性能仿真:从理论到实践的完整解析(附完整代码)
  • 审计- 3- 风险评估:内部控制
  • NVMe协议简介之AXI总线更新
  • MySQL锁机制
  • Linux 脚本文件编辑(vim)
  • 【接口测试】基础知识
  • 使用 HTML + JavaScript 实现图片裁剪上传功能
  • PCIe—TS1/TS2 之Polling.Configuration (二)
  • 【位运算】只出现⼀次的数字 II(medium)