【PhysUnits】17.5 实现常量除法(div.rs)
一、源码
这段代码实现了一个类型级别的除法运算系统,主要用于处理不同类型的数值在编译期间进行的除法操作。它使用了Rust的类型系统和trait来实现编译时的计算。
use core::ops::{Neg, Div};use super::basic::{Z0, B0, B1, P1, N1};
use crate::constant::{Integer, NonZero};
use crate::variable::{Var, Numeric};// ========== Basic Type Division Operations ==========
// ========== 基本类型除法运算 ==========// ========== 0 / All ===========
// Division of zero by any non-zero type
// 0 除以任何非零类型// 0 / 0 is illegal and not implemented
// 0 / 0 非法,未实现// 0 / NonZero = 0
impl<I: NonZero> Div<I> for Z0 {type Output = Self;#[inline(always)]fn div(self, _rhs: I) -> Self::Output {self // 0 / any non-zero = 0}
}// ========== 1 / All ===========
// Division of one by various types
// 1 除以各种类型// 1 / 0 is illegal and not implemented
// 1 / 0 非法,未实现// 1 / 1 = 1
impl Div<P1> for P1 {type Output = Self;#[inline(always)]fn div(self, _rhs: Self) -> Self::Output {P1}
}// 1/-1=-1
impl Div<N1> for P1 {type Output = N1;#[inline(always)]fn div(self, _rhs: N1) -> Self::Output {N1}
}// 1 / B0 has precision loss, returns f64
// 1 / B0 有精度损失,返回f64
impl<H:NonZero> Div<B0<H>> for P1 {type Output = f64;fn div(self, _: B0<H>) -> f64 {f64::from(1) / f64::from(B0::<H>::to_i32())}
}// 1 / B1 has precision loss, returns f64
// 1 / B1 有精度损失,返回f64
impl<H:NonZero> Div<B1<H>> for P1 {type Output = f64;fn div(self, _: B1<H>) -> f64 {f64::from(1) / f64::from(B1::<H>::to_i32())}
}// ========== -1 / All ===========
// Division of negative one by various types
// -1 除以各种类型// -1 / 0 is illegal and not implemented
// -1 / 0 非法,未实现// -1 / 1 = -1
impl Div<P1> for N1 {type Output = Self;#[inline(always)]fn div(self, _rhs: P1) -> Self::Output {N1}
}// -1/-1=1
impl Div<N1> for N1 {type Output = P1;#[inline(always)]fn div(self, _rhs: N1) -> Self::Output {P1}
}// -1 / B0 has precision loss, returns f64
// -1 / B0 有精度损失,返回f64
impl<H:NonZero> Div<B0<H>> for N1 {type Output = f64;fn div(self, _: B0<H>) -> f64 {f64::from(-1) / f64::from(B0::<H>::to_i32())}
}// -1 / B1 has precision loss, returns f64
// -1 / B1 有精度损失,返回f64
impl<H:NonZero> Div<B1<H>> for N1 {type Output = f64;fn div(self, _: B1<H>) -> f64 {f64::from(-1) / f64::from(B1::<H>::to_i32())}
}// ========== B0 / All ===========
// Division of binary type ending with 0 by various types
// 以0结尾的二进制类型除以各种类型// B0 / 0 is illegal and not implemented
// B0 / 0 非法,未实现// B0 / 1 = B0
impl<H: NonZero> Div<P1> for B0<H> {type Output = Self;#[inline(always)]fn div(self, _rhs: P1) -> Self::Output {self}
}// B0/-1=-B0
impl<H: NonZero> Div<N1> for B0<H>
where B0<H>: Neg,
{type Output = <B0<H> as Neg>::Output;#[inline(always)]fn div(self, _rhs: N1) -> Self::Output {-self}
}// B0 / B0 has precision loss, returns f64
// B0 / B0 有精度损失,返回f64
impl<H1:NonZero, H2:NonZero> Div<B0<H2>> for B0<H1> {type Output = f64;fn div(self, _: B0<H2>) -> f64 {f64::from(B0::<H1>::to_i32()) / f64::from(B0::<H2>::to_i32())}
}// B0 / B1 has precision loss, returns f64
// B0 / B1 有精度损失,返回f64
impl<H1:NonZero, H2:NonZero> Div<B1<H2>> for B0<H1> {type Output = f64;fn div(self, _: B1<H2>) -> f64 {f64::from(B0::<H1>::to_i32()) / f64::from(B1::<H2>::to_i32())}
}// ========== B1 / All ===========
// Division of binary type ending with 1 by various types
// 以1结尾的二进制类型除以各种类型// B1 / 0 is illegal and not implemented
// B1 / 0 非法,未实现// B1 / 1 = B1
impl<H: NonZero> Div<P1> for B1<H> {type Output = Self;#[inline(always)]fn div(self, _rhs: P1) -> Self::Output {self}
}// B1 / -1=-B1
impl<H: NonZero> Div<N1> for B1<H>
where B1<H>: Neg,
{type Output = <B1<H> as Neg>::Output;#[inline(always)]fn div(self, _rhs: N1) -> Self::Output {-self}
}// B1 / B0 has precision loss, returns f64
// B1 / B0 有精度损失,返回f64
impl<H1:NonZero, H2:NonZero> Div<B0<H2>> for B1<H1> {type Output = f64;fn div(self, _: B0<H2>) -> f64 {f64::from(B1::<H1>::to_i32()) / f64::from(B0::<H2>::to_i32())}
}// B1 / B1 has precision loss, returns f64
// B1 / B1 有精度损失,返回f64
impl<H1:NonZero, H2:NonZero> Div<B1<H2>> for B1<H1> {type Output = f64;fn div(self, _: B1<H2>) -> f64 {f64::from(B1::<H1>::to_i32()) / f64::from(B1::<H2>::to_i32())}
}// Quotient type alias
// 商类型别名
pub type Quot<A, B> = <A as Div<B>>::Output;// ========== Division with Var<T> ==========
// ========== 与Var<T>的除法运算 ==========// ========== 0 / Var<T> ==========
impl<T: Numeric + PartialEq> Div<Var<T>> for Z0 {type Output = Self;fn div(self, rhs: Var<T>) -> Self::Output {assert!(rhs.0 != T::from(0), "division by zero");self}
}// ========== 1 / Var<T> ==========
impl<T: Numeric> Div<Var<T>> for P1 {type Output = Var<T>;#[inline(always)]fn div(self, rhs: Var<T>) -> Self::Output {Var(T::from(1) / rhs.0)}
}// ========== -1 / Var<T> ==========
impl<T: Numeric> Div<Var<T>> for N1{type Output = <Var<T> as Neg>::Output;#[inline(always)]fn div(self, rhs: Var<T>) -> Self::Output {Var(T::from(-1) / rhs.0)}
}// ========== B0 / Var<T> ==========
impl<H: NonZero, T:Numeric> Div<Var<T>> for B0<H>
where B0<H>: Integer,Var<T>: Div<Var<T>>,
{type Output = Var<T>;#[inline(always)]fn div(self, rhs: Var<T>) -> Self::Output {Var(T::from(B0::<H>::to_i32()) / rhs.0)}
}// ========== B1 / Var<T> ==========impl<H: NonZero, T:Numeric> Div<Var<T>> for B1<H>
where B1<H>: Integer,Var<T>: Div<Var<T>>,
{type Output = Var<T>;#[inline(always)]fn div(self, rhs: Var<T>) -> Self::Output {Var(T::from(B1::<H>::to_i32()) / rhs.0)}
}
二、主要组成部分
- 基本类型定义
代码中使用了以下基本类型:
-
Z0: 表示数字0
-
P1: 表示数字+1
-
N1: 表示数字-1
-
B0: 表示以0结尾的二进制数(如2=0b10)
-
B1: 表示以1结尾的二进制数(如3=0b11)
- 核心trait实现
代码为这些类型实现了Div trait(除法运算),主要分为以下几类:
0的除法
-
0 / 非零类型 = 0
-
0 / 0 未实现(因为除零非法)
1的除法
-
1 / 1 = 1
-
1 / -1 = -1
-
1 / B0 或 1 / B1 返回f64(因为有精度损失)
-1的除法
-
-1 / 1 = -1
-
-1 / -1 = 1
-
-1 / B0 或 -1 / B1 返回f64
B0的除法
-
B0 / 1 = B0
-
B0 / -1 = -B0
-
B0 / B0 或 B0 / B1 返回f64
B1的除法
-
B1 / 1 = B1
-
B1 / -1 = -B1
-
B1 / B0 或 B1 / B1 返回f64
- 变量类型(Var)的除法
代码还实现了基本类型与变量类型Var的除法运算:
-
0 / Var: 检查除数不为零后返回0
-
1 / Var: 返回Var类型的结果
-
-1 / Var: 返回Var的负数结果
-
B0 / Var 和 B1 / Var: 将二进制数转换为T类型后计算
- 类型别名
定义了Quot<A, B>作为<A as Div>::Output的别名,方便使用。
三、设计特点
-
编译时计算:大部分运算在编译时完成,没有运行时开销
-
类型安全:通过trait bound确保运算的合法性
-
精度处理:对于可能丢失精度的运算(如整数相除)返回f64类型
-
错误预防:对除零操作进行了防范(未实现或运行时检查)
四、使用场景
这种类型级别的运算系统常用于需要编译时计算和类型安全的领域,如:
-
维度计算
-
单位系统
-
类型安全的矩阵运算
-
嵌入式系统等资源受限环境
代码中大量的#[inline(always)]属性确保了这些操作在运行时不会有额外开销,因为它们会在编译时被优化掉。