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

【typenum】 21 类型级别计算最大公约数(Gcd)

一、源码

代码实现了一个在类型级别计算最大公约数(GCD)的系统

  1. 定义(type_operators.rs)
/// A **type operator** that computes the [greatest common divisor][gcd] of `Self` and `Rhs`.
///
/// [gcd]: https://en.wikipedia.org/wiki/Greatest_common_divisor
///
/// # Example
///
/// ```rust
/// use unitrix::number::{Gcd, Unsigned, types::{U12, U8}};
///
/// assert_eq!(<U12 as Gcd<U8>>::Output::to_i32(), 4);
/// ```
pub trait Gcd<Rhs> {/// The greatest common divisor.type Output;
}
  1. 别名(operator_aliases.rs)
/// Alias for the associated type of `Gcd`: `Gcf<A, B> = <A as Gcd<B>>::Output>`
pub type Gcf<A, B> = <A as Gcd<B>>::Output;
  1. 无符号数实现(uint.rs)
/// gcd(0, 0) = 0
impl Gcd<U0> for U0 {type Output = U0;
}/// gcd(x, 0) = x
impl<X> Gcd<U0> for X
whereX: Unsigned + NonZero,
{type Output = X;
}/// gcd(0, y) = y
impl<Y> Gcd<Y> for U0
whereY: Unsigned + NonZero,
{type Output = Y;
}/// gcd(x, y) = 2*gcd(x/2, y/2) if both x and y even
impl<Xp, Yp> Gcd<Even<Yp>> for Even<Xp>
whereXp: Gcd<Yp>,Even<Xp>: NonZero,Even<Yp>: NonZero,
{type Output = UInt<Gcf<Xp, Yp>, B0>;
}/// gcd(x, y) = gcd(x, y/2) if x odd and y even
impl<Xp, Yp> Gcd<Even<Yp>> for Odd<Xp>
whereOdd<Xp>: Gcd<Yp>,Even<Yp>: NonZero,
{type Output = Gcf<Odd<Xp>, Yp>;
}/// gcd(x, y) = gcd(x/2, y) if x even and y odd
impl<Xp, Yp> Gcd<Odd<Yp>> for Even<Xp>
whereXp: Gcd<Odd<Yp>>,Even<Xp>: NonZero,
{type Output = Gcf<Xp, Odd<Yp>>;
}/// gcd(x, y) = gcd([max(x, y) - min(x, y)], min(x, y)) if both x and y odd
///
/// This will immediately invoke the case for x even and y odd because the difference of two odd
/// numbers is an even number.
impl<Xp, Yp> Gcd<Odd<Yp>> for Odd<Xp>
whereOdd<Xp>: Max<Odd<Yp>> + Min<Odd<Yp>>,Odd<Yp>: Max<Odd<Xp>> + Min<Odd<Xp>>,Maximum<Odd<Xp>, Odd<Yp>>: Sub<Minimum<Odd<Xp>, Odd<Yp>>>,Diff<Maximum<Odd<Xp>, Odd<Yp>>, Minimum<Odd<Xp>, Odd<Yp>>>: Gcd<Minimum<Odd<Xp>, Odd<Yp>>>,
{type Output =Gcf<Diff<Maximum<Odd<Xp>, Odd<Yp>>, Minimum<Odd<Xp>, Odd<Yp>>>, Minimum<Odd<Xp>, Odd<Yp>>>;
}#[cfg(test)]
mod gcd_tests {use super::*;use crate::consts::*;macro_rules! gcd_test {($( $a:ident, $b:ident => $c:ident ),* $(,)*) => {$(assert_eq!(<Gcf<$a, $b> as Unsigned>::to_usize(), $c::to_usize());assert_eq!(<Gcf<$b, $a> as Unsigned>::to_usize(), $c::to_usize());)*}}#[test]fn gcd() {gcd_test! {U0,   U0    => U0,U0,   U42   => U42,U12,  U8    => U4,U13,  U1013 => U1,  // Two primesU9,   U26   => U1,  // Not prime but coprimeU143, U273  => U13,U117, U273  => U39,}}
}

4.有符号整数实现(int.rs)

// ---------------------------------------------------------------------------------------
// Gcd
use crate::{Gcd, Gcf};impl Gcd<Z0> for Z0 {type Output = Z0;
}impl<U> Gcd<PInt<U>> for Z0
whereU: Unsigned + NonZero,
{type Output = PInt<U>;
}impl<U> Gcd<Z0> for PInt<U>
whereU: Unsigned + NonZero,
{type Output = PInt<U>;
}impl<U> Gcd<NInt<U>> for Z0
whereU: Unsigned + NonZero,
{type Output = PInt<U>;
}impl<U> Gcd<Z0> for NInt<U>
whereU: Unsigned + NonZero,
{type Output = PInt<U>;
}impl<U1, U2> Gcd<PInt<U2>> for PInt<U1>
whereU1: Unsigned + NonZero + Gcd<U2>,U2: Unsigned + NonZero,Gcf<U1, U2>: Unsigned + NonZero,
{type Output = PInt<Gcf<U1, U2>>;
}impl<U1, U2> Gcd<PInt<U2>> for NInt<U1>
whereU1: Unsigned + NonZero + Gcd<U2>,U2: Unsigned + NonZero,Gcf<U1, U2>: Unsigned + NonZero,
{type Output = PInt<Gcf<U1, U2>>;
}impl<U1, U2> Gcd<NInt<U2>> for PInt<U1>
whereU1: Unsigned + NonZero + Gcd<U2>,U2: Unsigned + NonZero,Gcf<U1, U2>: Unsigned + NonZero,
{type Output = PInt<Gcf<U1, U2>>;
}impl<U1, U2> Gcd<NInt<U2>> for NInt<U1>
whereU1: Unsigned + NonZero + Gcd<U2>,U2: Unsigned + NonZero,Gcf<U1, U2>: Unsigned + NonZero,
{type Output = PInt<Gcf<U1, U2>>;
}

二、核心概念

这是一个类型级编程的实现,使用Rust的trait系统在编译时计算GCD,而不是运行时。所有计算都在类型系统层面完成。

三、源码解析

  1. 定义(type_operators.rs)

pub trait Gcd<Rhs> {type Output;
}
  • 定义了一个泛型trait Gcd,其中Rhs是右操作数

  • 有一个关联类型Output表示计算结果

  • 这是一个类型运算符,不包含实际方法,只有类型关联

  1. 别名(operator_aliases.rs)

pub type Gcf<A, B> = <A as Gcd<B>>::Output;
  • 创建了类型别名Gcf(Greatest Common Factor)

  • 简化了访问GCD结果的语法:Gcf<A, B> 等价于 <A as Gcd>::Output

  1. 无符号数实现(uint.rs)

实现了欧几里得算法的类型级版本:

基本情况:

  • gcd(0, 0) = 0

  • gcd(x, 0) = x (x ≠ 0)

  • gcd(0, y) = y (y ≠ 0)

递归情况:

  • 双偶数:gcd(x, y) = 2 * gcd(x/2, y/2)

  • x奇y偶:gcd(x, y) = gcd(x, y/2)

  • x偶y奇:gcd(x, y) = gcd(x/2, y)

  • 双奇数:gcd(x, y) = gcd(|x-y|, min(x,y))(利用两奇数差为偶数的性质)

  1. 有符号整数实现(int.rs)

处理有符号整数的情况:

  • gcd(0, 0) = 0

  • gcd(0, ±y) = |y| (y ≠ 0)

  • gcd(±x, 0) = |x| (x ≠ 0)

  • gcd(±x, ±y) = gcd(|x|, |y|) - 结果总是正数

四、技术特点

  1. 类型级编程
  • 所有计算在编译时完成

  • 使用trait系统和关联类型表达计算

  • 结果在类型系统中可用,无需运行时计算

  1. 递归实现

基于欧几里得算法,通过模式匹配(奇偶性)选择正确的计算路径
3. 零成本抽象

  • 编译时计算,运行时无开销

  • 类型安全:确保所有操作都在有效范围内

五、使用示例


// 编译时计算 gcd(12, 8) = 4
type Result = Gcf<U12, U8>;
assert_eq!(Result::to_i32(), 4); // 编译时已知结果为4

六、设计优势

  • 编译时验证:类型系统确保计算正确性

  • 零运行时开销:所有计算在编译期完成

  • 类型安全:防止无效操作(如除以零)

  • 模块化设计:清晰的trait层次和实现分离

这是一个典型的使用Rust类型系统进行编译时计算的例子,展示了如何利用trait系统和关联类型来实现复杂的数学运算。

http://www.dtcms.com/a/343872.html

相关文章:

  • map和set的使⽤
  • 52 C++ 现代C++编程艺术1-禁止隐式转换关键字explicit
  • Qt中用于图像缩放的核⼼⽅法QPixmap::scaled
  • 编写Linux下设备驱动时两种方案:内核态驱动开发和用户态驱动开发
  • --- 使用OpenFeign来优雅的对服务进行调用 ---
  • vue2怎么修改el-table样式
  • 金融风控AI引擎:实时反欺诈系统的架构设计与实现
  • CTFSHOW | 其他篇题解(二)web417 - web437
  • 进程间通信-IPC机制
  • 【开发日记】SpringBoot 实现支持多个微信小程序的登录
  • 初始数据结构——反射、枚举与Lambda的奇幻冒险
  • 如何理解AP服务发现协议中“如果某项服务需要在多个网络接口上提供,则应为每个网络接口使用一个独立的服务器服务实例。”?
  • 《Linux 网络编程一:网络编程导论及UDP 服务器的创建与数据接收》
  • “我 / 店模式” 靠联盟 + 积分破局,实现三方共赢!
  • 【Oracle】内存管理实战指南:ASMM vs AMM 配置全解析
  • Rust Web开发指南 第一章
  • 服务发现实例和服务实例是不同的
  • 血管介入医疗AI发展最新方向与编程变革:从外周、神经到冠脉的全面解析
  • RabbitMQ面试精讲 Day 27:常见故障排查与分析
  • yggjs_rlayout使用教程 v0.1.0
  • Linux系统之Ubuntu安装cockpit管理工具
  • Jenkins发布spring项目踩坑——nohup java -jar发布后显示成功,但实际jps查询并未运行
  • React 学习笔记1 组件、State
  • 【Tech Arch】Hadoop YARN 大数据集群的 “资源管家”
  • 企业级知识库+智能客服地大模型对比表
  • 实现自己的AI视频监控系统-第一章-视频拉流与解码4(重点)
  • MATLAB启动路径MATLAB202X/bin更改问题
  • 【Python】-- 机器学习项目 - 基于逻辑回归算法的乳腺癌数据集分类
  • 理解AI 智能体:智能体架构
  • DAY14-新世纪DL(DeepLearning/深度学习)战士:破(优化算法)2