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

news/2025/10/8 22:16:36/文章来源:https://www.cnblogs.com/lxjshuju/p/19130200

一、源码

这段代码是用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>
where
H: 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>
where
H: 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 Z0
let _: Z0 = Z0 >>
Z0
;
let _: Z0 = Z0 >>
P1
;
// Test P1
let _: P1 = P1 >>
Z0
;
let _: Z0 = P1 >>
P1
;
// Test N1
let _: N1 = N1 >>
Z0
;
let _: N1 = N1 >>
P1
;
// Test B0
let b0: B0<
P1>
= B0::new(
)
;
let _: B0<
P1>
= b0 >>
Z0
;
let _: P1 = b0 >>
P1
;
// Test B1
let b1: B1<
P1>
= B1::new(
)
;
let _: B1<
P1>
= b1 >>
Z0
;
let _: P1 = b1 >>
P1
;
}
}

二、基本概念

  1. 类型定义:
  1. 核心trait:

三、实现逻辑

  1. Z0(零)的右移:
  1. P1(+1)的右移:
  1. N1(-1)的右移:
  1. B0(以0结尾的二进制数)的右移:
  1. B1(以1结尾的二进制数)的右移:
递归实现

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

impl<
H: NonZero
, R: Unsigned + NonZero + NonOne + Sub1>
Shr<
R>
for B0<
H>
where
H: 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.mzph.cn/news/931999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[论文阅读]PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

10. 模型与视图

一、模型与视图模型/视图架构包含三部分:模型(Model)是应用对象,用来表示数据;视图(View)是模型的用户界面,用来显示数据;委托(Delegate,也被称为 代理)可以定制数据的渲染和编辑方式。通过数据和界面进行…

网站域名备案信息查询wordpress无法查看站点

为啥我会使用pgbackrest进行备份&#xff1f;因为postgresql没有自带的差异备份工具。。。而我们在生产环境上&#xff0c;一般都需要用到差异备份或者增量备份。我们的备份策略基本是&#xff0c;1天1次完整备份&#xff0c;1个小时1次差异备份。如果只需要完整备份&#xff0…

[KaibaMath]1004 关于f(x,y) = [x]+[y] - [x+y]的平移稳定性

[KaibaMath]1004 关于f(x,y) = [x]+[y] - [x+y]的平移稳定性令f(x,y) = [x]+[y] - [x+y], g(x, y) = {x} + {y} - {x+y},则f(x, y) + g(x, y)= 0。 注意f(x, y)和g(x, y)均具有平移稳定性。 例如:f(x+M, y+N) = f(x,…

Mac OS 问题与技巧

docker Desktop中登录ubuntu后出现向上方向键不识别的问题:# 从 sh 切换到 bash /bin/bash通过方向键找到上一个命令: root@a8cf29654a52:/opt/csm# pwd /opt/csm root@a8cf29654a52:/opt/csm# pwd /opt/csm root@a8…

数据分析对网站建设的重要性福田营销型网站建站推广外包

文章目录 前言ts和js的区别&#xff1f;什么是Typescript的方法重载&#xff1f;Typescript中never 和 void 的区别&#xff1f;typescript 中的 is 关键字有什么用&#xff1f;TypeScript支持的访问修饰符有哪些&#xff1f;如何定义一个数组&#xff0c;它的元素可能是字符串…

黑龙江省建设教育网站查询小企业网站建设计划书

目录 1、什么是缓存 2、为什么使用Redis作为MySQL的缓存 3、缓存的更新策略 3.1、策略一&#xff1a;定期生成 3.2、策略二&#xff1a;实时生成 内存淘汰策略【面试重点】 4、缓存预热(Cache preheating)【面试重点】 5、缓存穿透(Cache penetration)【面试重点】 6、…

《算法设计与分析》第一章学习记录

一、互联网大公司的编码规范 核心目标是协同、质量、效率与安全。 1.命名规范 变量、函数、类名必须能清晰地表达其意图,避免使用 a, b, c, tmp 等无意义名称。严格遵守 camelCase、PascalCase、snake_case 等约定,并…

mcp_server

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" https://github.com/runekaagaard/mcp-alchemy"imes": { "command": "uvx", &qu…

香山红叶建设有限公司网站虚拟主机安装wordpress

一、代理模式 代理模式定义&#xff1a;为其他对象提供一种代理以控制对这个对象的访问。 上面类图中有一个订单接口类(OrderService)、一个订单实现类(OrderServiceImpl)&#xff0c;订单模块的业务相对复杂和重要&#xff0c;如果这时候要在方法执行前后加上日志&#xff0c…

2025.10 国庆集训模拟赛总结

把门视为点,找环,答案就是环的长度先预处理前缀和 然后预处理f[i]表示满足j<i且aj==ai的最大的j。 答案就变成了:第一问用树套树类结构维护 第二问直接二分第一问就行,因为第一问我们在先做了。 树套树太难写,…

详细介绍:https和http有什么区别-http各个版本有什么区别

详细介绍:https和http有什么区别-http各个版本有什么区别pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consola…

CF2150F Cycle Closing

感觉上判是否能一次完成是困难的。设两次的路径长度分别为 \(a, b\),考虑一些特殊情况。 题目一定有解,考虑取出一棵生成树。可以发现,第二次操作时的边数实际上很多,感觉上对于 \(b\) 不能限制得太小。考虑 \(a\)…

Easysearch 字段隐身之谜:source_reuse 与 ignore_above 的陷阱解析

背景问题 前阵子,社区有小伙伴在使用 Easysearch 的数据压缩功能时发现,在开启 source_reuse 和 ZSTD 后,一个字段的内容看不到了。 索引的设置如下: {......"settings": {"index": {"co…

QOJ856 Cactus 广义串并联图

题意 给定一棵仙人掌, 你需要用 \(k\) 种颜色给每个结点染色, 且保证有边相连的结点的颜色不相同, 求染色的方案数对 \(10^9+7\) 取模的结果。仙人掌定义为一张特殊的无向图, 其中每条边至多在一个简单环上。 题解 因为…

CF2152 订题

context A 除了最小的数字每种数字都会占用一次,去重后直接输出 \(2n-1\) 即可。 B 太神秘了,先咕咕咕。 C 发现如果一个区间内存在至少一个长度 \(\ge 2\) 的同色连续段,那么这个连续段可以通过删除两个同色之间的…

TortoiseSVN账号切换 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

房产中介 网站开发天津招投标天津建设工程信息网

电脑 远程桌面连接你的凭据不工作解决方法 方法/步骤 第一步我们首先需要知道远程桌面连接你的凭据不工作原因是&#xff0c;远程的电脑拒绝了访问&#xff0c;需要设置在远程的电脑上设置安全选项&#xff0c;按winR键&#xff0c;打开运行&#xff0c;输入“gpedit.msc”&a…

GJ Round 2025赛季

Round 1 (9.1) A给定正整数序列 \(a_1,a_2,\cdots,a_n\),对于 \(\forall k \in [0,n] \cap \mathbb Z\),完成以下问题: 令 \(S \subseteq A = \{1,2,\cdots,n\}\),当且仅当存在一个集合 \(T \subseteq S\),满足 \…

resolvers: [ElementPlusResolver()] 有什么用? - 详解

resolvers: [ElementPlusResolver()] 有什么用? - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…