【PhysUnits】15.10 类型级别的乘法运算(mul.rs)

一、源码

这段代码实现了类型级别的乘法运算,使用Rust的类型系统来表示和执行整数乘法。这是典型的类型级编程(type-level programming)示例,常用于在编译期进行数学运算。

rust 复制代码
use core::ops::{Mul, Neg};
use super::basic::{Z0, P1, N1, B0, B1, Integer, NonZero};
use super::add::Add;

// ========== Basic Type Multiplication ==========
// ========== 基本类型乘法 ==========

// ========== 0 * All ==========
// ========== 零乘以任何数 ==========
impl<I: Integer> Mul<I> for Z0 {
    type Output = Self;
    #[inline(always)]
    fn mul(self, _rhs: I) -> Self::Output {
        self  // 0 * any = 0
    }
}

// ========== 1 * All ==========
// ========== 一乘以任何数 ==========
impl<I: Integer> Mul<I> for P1 {
    type Output = I;
    #[inline(always)]
    fn mul(self, rhs: I) -> Self::Output {
        rhs  // 1 * x = x
    }
}

// ========== -1 * All ==========
// ========== 负一乘以任何数 ==========
impl<I: Integer + Neg> Mul<I> for N1 {
    type Output = I::Output;
    #[inline(always)]
    fn mul(self, rhs: I) -> Self::Output {
        -rhs  // -1 * x = -x
    }
}

// ========== B0 * All ==========
// ========== 以0结尾的二进制数乘法 ==========

// B0 * Z0 = 0
// 以0结尾的数乘以零
impl<H: NonZero> Mul<Z0> for B0<H> {
    type Output = Z0;
    #[inline(always)]
    fn mul(self, _rhs: Z0) -> Self::Output {
        Z0  // x * 0 = 0
    }
}

// B0<NonZero> * NonZero = B0<NonZero * I>
// 以0结尾的数乘以非零数
//
// Explanation:
//    B0<P> * I = (2*P)*I = 2*(P*I) = B0<P * I>
//    B0<N> * I = -B0<-N> * I = -B0<(-N)*I> = B0<N * I>
//    Therefore, B0<NonZero> * I = B0<NonZero * I>
//
// 说明:
//    B0<P> * I = (2*P)*I = 2*(P*I) = B0<P * I>
//    B0<N> * I = -B0<-N> * I = -B0<(-N)*I> = B0<N * I>
//    因此,B0<NonZero> * I = B0<NonZero * I>
impl<H: NonZero + Mul<I>, I: NonZero> Mul<I> for B0<H> {
    type Output = B0<H::Output>;
    #[inline(always)]
    fn mul(self, _rhs: I) -> Self::Output {
        B0::new()  // 构造新的B0类型
    }
}

// ========== B1 * All ==========
// ========== 以1结尾的二进制数乘法 ==========

// B1 * Z0 = 0
// 以1结尾的数乘以零
impl<H: NonZero> Mul<Z0> for B1<H> {
    type Output = Z0;
    #[inline(always)]
    fn mul(self, _rhs: Z0) -> Self::Output {
        Z0  // x * 0 = 0
    }
}

// B1<NonZero> * NonZero = I + B0<NonZero * I>
// 以1结尾的数乘以非零数
//
// Explanation:
//    B1<P> * I = (1 + B0<P>) * I = I + B0<P * I>
//    B1<N> * I = -B1<!N> * I = -I * ((2*!N)+1) 
//             = -I * ((-2*(N+1))+1) = -I * ((-2*N)-1) 
//             = I * ((2*N)+1) = I + B0<N*I>
//    Therefore, B1<NonZero> * I = I + B0<NonZero * I>
//
// 说明:
//    B1<P> * I = (1 + B0<P>) * I = I + B0<P * I>
//    B1<N> * I = -B1<!N> * I = -I * ((2*!N)+1)
//             = -I * ((-2*(N+1))+1) = -I * ((-2*N)-1)
//             = I * ((2*N)+1) = I + B0<N*I>
//    因此,B1<NonZero> * I = I + B0<NonZero * I>
impl<H: NonZero + Mul<I>, I: NonZero + Add<B0<<H as Mul<I>>::Output>>> Mul<I> for B1<H> {
    type Output = I::Output;
    #[inline(always)]
    fn mul(self, i: I) -> Self::Output {
        i + B0::new()  // I + B0<H*I>
    }
}

/// Type alias for multiplication: `Prod<A, B> = <A as Mul<B>>::Output`
/// 乘法运算的类型别名:`Prod<A, B> = <A as Mul<B>>::Output`
pub type Prod<A, B> = <A as Mul<B>>::Output;

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_basic_multiplication() {
        // Test Z0 (0 * anything = 0)
        // 测试零的乘法
        let _: Z0 = Z0 * Z0;
        let _: Z0 = Z0 * P1;
        let _: Z0 = Z0 * N1;
        
        // Test P1 (1 * anything = anything)
        // 测试正一的乘法
        let _: Z0 = P1 * Z0;
        let _: P1 = P1 * P1;
        let _: N1 = P1 * N1;
        
        // Test N1 (-1 * anything = -anything)
        // 测试负一的乘法
        let _: Z0 = N1 * Z0;
        let _: N1 = N1 * P1;
        let _: P1 = N1 * N1;
    }
    
    #[test]
    fn test_b0_multiplication() {
        // B0<P1> represents binary 10 (decimal 2)
        // B0<P1> 表示二进制10(十进制2)
        let b0_p1: B0<P1> = B0::new();
        
        // 2 * 0 = 0
        let _: Z0 = b0_p1 * Z0;
        
        // 2 * 1 = 2 (B0<P1>)
        let _: B0<P1> = b0_p1 * P1;
        
        // 2 * (-1) = -2 (B0<N1>)
        let _: B0<N1> = b0_p1 * N1;
    }
    
    #[test]
    fn test_b1_multiplication() {
        // B1<P1> represents binary 11 (decimal 3)
        // B1<P1> 表示二进制11(十进制3)
        let b1_p1: B1<P1> = B1::new();
        
        // 3 * 0 = 0
        let _: Z0 = b1_p1 * Z0;
        
        // 3 * 1 = 3 (B1<P1>)
        // Note: This requires addition to be properly implemented
        // 注意:这需要加法正确实现
        // let _: B1<P1> = b1_p1 * P1;
        
        // 3 * (-1) = -3 (B1<N1>)
        // let _: B1<N1> = b1_p1 * N1;
    }
    
    // Helper function to create values
    // 辅助函数创建值
    fn _create_values() {
        let _z0 = Z0;
        let _p1 = P1;
        let _n1 = N1;
        let _b0_p1: B0<P1> = B0::new();
        let _b1_p1: B1<P1> = B1::new();
    }
}

二、基本概念

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

  • P1 表示正1

  • N1 表示负1

  • B0 表示以0结尾的二进制数(相当于2*H)

  • B1 表示以1结尾的二进制数(相当于2*H + 1)

  1. 核心trait:
  • Integer - 表示整数类型

  • NonZero - 表示非零整数类型

  • Mul - Rust的标准乘法trait

三、乘法实现

  1. 零的乘法 (Z0)
rust 复制代码
impl<I: Integer> Mul<I> for Z0 {
    type Output = Self;
    fn mul(self, _rhs: I) -> Self::Output {
        self  // 0 * any = 0
    }
}

任何数乘以零都等于零,返回Z0类型。

  1. 一的乘法 (P1)
rust 复制代码
impl<I: Integer> Mul<I> for P1 {
    type Output = I;
    fn mul(self, rhs: I) -> Self::Output {
        rhs  // 1 * x = x
    }
}

一乘以任何数等于该数本身,返回输入类型。

  1. 负一的乘法 (N1)
rust 复制代码
impl<I: Integer + Neg> Mul<I> for N1 {
    type Output = I::Output;
    fn mul(self, rhs: I) -> Self::Output {
        -rhs  // -1 * x = -x
    }
}

负一乘以任何数等于该数的负数,要求输入类型实现了Neg trait。

  1. 以0结尾的二进制数乘法 (B0)
rust 复制代码
impl<H: NonZero> Mul<Z0> for B0<H> {
    type Output = Z0;
    fn mul(self, _rhs: Z0) -> Self::Output {
        Z0  // x * 0 = 0
    }
}

impl<H: NonZero + Mul<I>, I: NonZero> Mul<I> for B0<H> {
    type Output = B0<H::Output>;
    fn mul(self, _rhs: I) -> Self::Output {
        B0::new()  // B0<H * I>
    }
}
  • 乘以零返回零

  • 乘以非零数:B0 * I = B0<HI>(因为B0表示2 H,所以2H * I = 2(H*I))

  1. 以1结尾的二进制数乘法 (B1)
rust 复制代码
impl<H: NonZero> Mul<Z0> for B1<H> {
    type Output = Z0;
    fn mul(self, _rhs: Z0) -> Self::Output {
        Z0  // x * 0 = 0
    }
}

impl<H: NonZero + Mul<I>, I: NonZero + Add<B0<<H as Mul<I>>::Output>>> Mul<I> for B1<H> {
    type Output = I::Output;
    fn mul(self, i: I) -> Self::Output {
        i + B0::new()  // I + B0<H*I>
    }
}
  • 乘以零返回零

  • 乘以非零数:B1 * I = I + B0<HI>(因为B1表示2 H + 1,所以(2H + 1) * I = I + 2H*I)

四、类型别名

rust 复制代码
pub type Prod<A, B> = <A as Mul<B>>::Output;

提供方便的别名Prod<A, B>来表示A * B的类型。

五、测试用例

测试代码验证了各种乘法场景:

  1. 基本乘法(零、正一、负一)

  2. B0类型的乘法

  3. B1类型的乘法

这种类型级编程技术常用于需要编译期计算的场景,如模板元编程、维度检查等,可以在编译期捕获错误而不引入运行时开销。

相关推荐
红烧code11 小时前
【Rust GUI开发入门】编写一个本地音乐播放器(4. 绘制按钮组件)
rust·gui·svg·slint
朝阳58113 小时前
使用过程宏实现自动化新增功能
后端·rust
JordanHaidee14 小时前
【Rust GUI开发入门】编写一个本地音乐播放器(8. 从文件中提取歌曲元信息)
rust
清心91517 小时前
Windows系统Rust安装与配置,解决安装慢问题
rust
清心91517 小时前
Windows系统Rust安装,自定义安装目录
rust
恒云客19 小时前
Rust开发环境配置
开发语言·后端·rust
红烧code2 天前
【Rust GUI开发入门】编写一个本地音乐播放器(1. 主要技术选型&架构设计)
rust·gui·slint·rodio·lofty
JordanHaidee2 天前
【Rust GUI开发入门】编写一个本地音乐播放器(3. UI与后台线程通信)
rust
Source.Liu2 天前
【mdBook】1 安装
笔记·rust·markdown
Vallelonga2 天前
Rust 中的 static 和 const
开发语言·经验分享·rust