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

【PhysUnits】1 SI Prefixes 实现解析(prefix.rs)

一、源码

// prefix.rs
//! SI Prefixes (国际单位制词头)
//! 
//! 提供所有标准SI词头用于单位转换,仅处理10的幂次
//! 
//! Provides all standard SI prefixes for unit conversion, handling only powers of 10.use typenum::{Z0, P1, P2, P3, P6, P9, P12, P15, P18, P21, P24, P27, P30,N1, N2, N3, N6, N9, N12, N15, N18, N21, N24, N27, N30,Integer, IsEqual, Sum, Diff
};
use std::marker::PhantomData;
use std::ops::{Add, Sub, Mul, Div};/// PrefixLike trait defines operations related to SI prefixes
/// SI词头特质定义了与SI词头相关的操作
pub trait PrefixLike {/// The symbol of the prefix (e.g. "k" for kilo)/// 词头符号(例如"k"表示千)const SYMBOL: &'static str;/// The exponent of the prefix (e.g. 3 for kilo which means 10^3)/// 词头的幂次(例如3表示千,即10^3)const EXPONENT: i32;/// Whether the prefix is positive (exponent > 0)/// 是否是正词头(幂次>0)const IS_POSITIVE: bool = { Self::EXPONENT > 0 };/// Whether the prefix is negative (exponent < 0)/// 是否是负词头(幂次<0)const IS_NEGATIVE: bool = { Self::EXPONENT < 0 };
}/// Prefix struct representing a power of 10
/// 词头结构体,表示10的幂次
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Prefix<Exp: Integer>(PhantomData<Exp>);// 实现构造函数
impl<Exp: Integer> Prefix<Exp> {/// Create a new Prefix instance/// 创建一个新的词头实例pub fn new() -> Self {Prefix(PhantomData)}
}// 为各类型实现PrefixLike
// Implement PrefixLike for various types// 无词头 / No prefix
impl PrefixLike for Prefix<Z0> {const SYMBOL: &'static str = "";const EXPONENT: i32 = 0;
}// 正词头 / Positive prefixes
impl PrefixLike for Prefix<P1> {const SYMBOL: &'static str = "da";const EXPONENT: i32 = 1;
}impl PrefixLike for Prefix<P2> {const SYMBOL: &'static str = "h";const EXPONENT: i32 = 2;
}impl PrefixLike for Prefix<P3> {const SYMBOL: &'static str = "k";const EXPONENT: i32 = 3;
}impl PrefixLike for Prefix<P6> {const SYMBOL: &'static str = "M";const EXPONENT: i32 = 6;
}impl PrefixLike for Prefix<P9> {const SYMBOL: &'static str = "G";const EXPONENT: i32 = 9;
}impl PrefixLike for Prefix<P12> {const SYMBOL: &'static str = "T";const EXPONENT: i32 = 12;
}impl PrefixLike for Prefix<P15> {const SYMBOL: &'static str = "P";const EXPONENT: i32 = 15;
}impl PrefixLike for Prefix<P18> {const SYMBOL: &'static str = "E";const EXPONENT: i32 = 18;
}impl PrefixLike for Prefix<P21> {const SYMBOL: &'static str = "Z";const EXPONENT: i32 = 21;
}impl PrefixLike for Prefix<P24> {const SYMBOL: &'static str = "Y";const EXPONENT: i32 = 24;
}impl PrefixLike for Prefix<P27> {const SYMBOL: &'static str = "R";const EXPONENT: i32 = 27;
}impl PrefixLike for Prefix<P30> {const SYMBOL: &'static str = "Q";const EXPONENT: i32 = 30;
}// 负词头 / Negative prefixes
impl PrefixLike for Prefix<N1> {const SYMBOL: &'static str = "d";const EXPONENT: i32 = -1;
}impl PrefixLike for Prefix<N2> {const SYMBOL: &'static str = "c";const EXPONENT: i32 = -2;
}impl PrefixLike for Prefix<N3> {const SYMBOL: &'static str = "m";const EXPONENT: i32 = -3;
}impl PrefixLike for Prefix<N6> {const SYMBOL: &'static str = "μ";const EXPONENT: i32 = -6;
}impl PrefixLike for Prefix<N9> {const SYMBOL: &'static str = "n";const EXPONENT: i32 = -9;
}impl PrefixLike for Prefix<N12> {const SYMBOL: &'static str = "p";const EXPONENT: i32 = -12;
}impl PrefixLike for Prefix<N15> {const SYMBOL: &'static str = "f";const EXPONENT: i32 = -15;
}impl PrefixLike for Prefix<N18> {const SYMBOL: &'static str = "a";const EXPONENT: i32 = -18;
}impl PrefixLike for Prefix<N21> {const SYMBOL: &'static str = "z";const EXPONENT: i32 = -21;
}impl PrefixLike for Prefix<N24> {const SYMBOL: &'static str = "y";const EXPONENT: i32 = -24;
}impl PrefixLike for Prefix<N27> {const SYMBOL: &'static str = "r";const EXPONENT: i32 = -27;
}impl PrefixLike for Prefix<N30> {const SYMBOL: &'static str = "q";const EXPONENT: i32 = -30;
}// ========== 基本操作实现 ==========
// ========== Basic Operations Implementation ==========/// 实现词头乘法 (10^a * 10^b = 10^(a+b))
/// Implements prefix multiplication (10^a * 10^b = 10^(a+b))
impl<Ea, Eb> Mul<Prefix<Eb>> for Prefix<Ea>
whereEa: Integer + Add<Eb>,Eb: Integer,Sum<Ea, Eb>: Integer,
{type Output = Prefix<Sum<Ea, Eb>>;fn mul(self, _: Prefix<Eb>) -> Self::Output {Prefix::new()}
}/// 实现词头除法 (10^a / 10^b = 10^(a-b))
/// Implements prefix division (10^a / 10^b = 10^(a-b))
impl<Ea, Eb> Div<Prefix<Eb>> for Prefix<Ea>
whereEa: Integer + Sub<Eb>,Eb: Integer,Diff<Ea, Eb>: Integer,
{type Output = Prefix<Diff<Ea, Eb>>;fn div(self, _: Prefix<Eb>) -> Self::Output {Prefix::new()}
}// ========== 实用类型别名 ==========
// ========== Useful Type Aliases ==========pub type NoPrefix = Prefix<Z0>;
pub type Deca = Prefix<P1>;
pub type Hecto = Prefix<P2>;
pub type Kilo = Prefix<P3>;
pub type Mega = Prefix<P6>;
pub type Giga = Prefix<P9>;
pub type Tera = Prefix<P12>;
pub type Peta = Prefix<P15>;
pub type Exa = Prefix<P18>;
pub type Zetta = Prefix<P21>;
pub type Yotta = Prefix<P24>;
pub type Ronna = Prefix<P27>;
pub type Quetta = Prefix<P30>;pub type Deci = Prefix<N1>;
pub type Centi = Prefix<N2>;
pub type Milli = Prefix<N3>;
pub type Micro = Prefix<N6>;
pub type Nano = Prefix<N9>;
pub type Pico = Prefix<N12>;
pub type Femto = Prefix<N15>;
pub type Atto = Prefix<N18>;
pub type Zepto = Prefix<N21>;
pub type Yocto = Prefix<N24>;
pub type Ronto = Prefix<N27>;
pub type Quecto = Prefix<N30>;/// 词头乘法结果类型 / Prefix multiplication result type
pub type PrefixMul<A, B> = <A as Mul<B>>::Output;/// 词头除法结果类型 / Prefix division result type
pub type PrefixDiv<A, B> = <A as Div<B>>::Output;/// 词头相等判断类型 / Prefix equality comparison type
pub type PrefixEq<A, B> = <A as IsEqual<B>>::Output;// ========== 调试和测试代码 ==========
// ========== Debug and Test Code ==========#[cfg(test)]
mod tests {use super::*;/// 测试词头属性和基本操作/// Test prefix properties and basic operations#[test]fn test_prefix_properties() {assert_eq!(Kilo::SYMBOL, "k");assert_eq!(Kilo::EXPONENT, 3);assert!(Kilo::IS_POSITIVE);assert!(!Kilo::IS_NEGATIVE);assert_eq!(Milli::SYMBOL, "m");assert_eq!(Milli::EXPONENT, -3);assert!(!Milli::IS_POSITIVE);assert!(Milli::IS_NEGATIVE);}#[test]fn test_prefix_multiplication() {let kilo = Prefix::<P3>::new();let milli = Prefix::<N3>::new();// k * m = 10^3 * 10^-3 = 10^0let result = kilo * milli;assert_eq!(result, Prefix::<Z0>::new());// M * k = 10^6 * 10^3 = 10^9 (Giga)let mega = Prefix::<P6>::new();let kilo = Prefix::<P3>::new();let result = mega * kilo;assert_eq!(result, Prefix::<P9>::new());}#[test]fn test_prefix_division() {let kilo = Prefix::<P3>::new();let milli = Prefix::<N3>::new();// k / m = 10^3 / 10^-3 = 10^6 (Mega)let result = kilo / milli;assert_eq!(result, Prefix::<P6>::new());// m / k = 10^-3 / 10^3 = 10^-6 (Micro)let result = milli / kilo;assert_eq!(result, Prefix::<N6>::new());}#[test]fn test_type_aliases() {assert_eq!(<PrefixMul<Kilo, Milli> as PrefixLike>::EXPONENT, 0);assert_eq!(<PrefixDiv<Mega, Kilo> as PrefixLike>::EXPONENT, 3);}
}/// 调试输出实现
/// Debug output implementation
impl<Exp: Integer> std::fmt::Display for Prefix<Exp>
wherePrefix<Exp>: PrefixLike,
{fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {write!(f, "Prefix({}, 10^{})", Self::SYMBOL, Self::EXPONENT)}
}

二、核心结构

pub trait PrefixLike {const SYMBOL: &'static str;const EXPONENT: i32;const IS_POSITIVE: bool = { Self::EXPONENT > 0 };const IS_NEGATIVE: bool = { Self::EXPONENT < 0 };
}

三、类型定义示例

// 正词头
pub type Kilo = Prefix<P3>;    // 10³
pub type Mega = Prefix<P6>;    // 10⁶// 负词头  
pub type Milli = Prefix<N3>;   // 10⁻³
pub type Micro = Prefix<N6>;  // 10⁻⁶

四、运算实现

// 乘法实现
impl<Ea, Eb> Mul<Prefix<Eb>> for Prefix<Ea>
whereEa: Integer + Add<Eb>,Eb: Integer,Sum<Ea, Eb>: Integer,
{type Output = Prefix<Sum<Ea, Eb>>;fn mul(self, _: Prefix<Eb>) -> Self::Output {Prefix::new()}
}

五、测试用例

#[test]
fn test_prefix_multiplication() {let kilo = Prefix::<P3>::new();let milli = Prefix::<N3>::new();let result = kilo * milli;  // 应得到无前缀assert_eq!(result, Prefix::<Z0>::new());
}

六、关键特性

  1. 零成本抽象 - 所有计算在编译期完成
  2. 类型安全 - 通过类型系统保证运算合法性
  3. 完整覆盖 - 支持所有标准SI词头
  4. 可组合性 - 支持词头间的各种运算

七、使用示例

let distance = 1.0 * Kilo::new();  // 1千米
let length = distance * Milli::new();  // 转换为米

相关文章:

  • 常识补充(NVIDIA NVLink技术:打破GPU通信瓶颈的革命性互联技术)
  • 前端基础之《Vue(14)—组件通信》
  • 【LLM】什么是 MCPACPACA
  • 塔能水泵节能方案:精准驱动工厂能耗优化
  • 5.6刷题并查集
  • opencv实战:银行卡卡号识别
  • 即插即用!长安汽车复旦提出LMPOcc:长期记忆先验实现占用预测任务新SOTA
  • 富文本编辑器的第三方库ProseMirror
  • C++复习2
  • C#问题 加载格式不正确解决方法
  • HA: Natraj靶场渗透测试
  • Java并发编程-锁(一)
  • 工业质检/缺陷检测领域最新顶会期刊论文收集整理 | AAAI 2025【持续更新中】
  • [python] str
  • 线性回归练习1
  • 隐私计算框架FATE二次开发心得整理(工业场景实践)
  • 图像处理软件imgPro—调参救星!
  • 『Linux_网络』 基于状态机的Connect断线重连
  • 哈希表的设计
  • 基于STM32、HAL库的NS2009 触摸屏控制器驱动程序设计
  • 印巴局势快速升级,外交部:呼吁印巴以和平稳定的大局为重
  • 证监会主席吴清:我们资本市场最重要的特征是“靠谱”
  • 潘功胜:将下调个人住房公积金贷款利率0.25个百分点
  • 86岁书画家、美术教育家、吴昌硕嫡裔曾孙吴民先离世
  • 公安部:“五一”假期全国社会大局稳定,治安秩序良好
  • 路遇交通事故镇干部冲进火海救人,已申报见义勇为