这段代码实现了一个类型级别的数值系统,支持多种数字类型(整数、定点数、变量)之间的减法运算。它使用了 Rust 的类型系统特性(traits 和关联类型)在编译期完成数值计算。
//小数、浮点数与Var 的混合计算未实现
use core::ops::{Neg, Not, Add, Sub};
use crate::number::{
Z0, P1, N1, B0, B1, FixedPoint, Var,
NonZero, Primitive, TypedInt, Unsigned,
Add1, Sub1, IfB0, IfB1,
};
// ==================== 带借位减法 Trait ====================
/// 带借位减法运算
/// Subtraction with borrow operation
///
/// 表示 a - b - 1 的运算 (相当于 a - (b + 1))
/// Represents the operation of a - b - 1 (equivalent to a - (b + 1))
/// 说明:有借位表示有低位数,本位 NonZero
pub trait SubWithBorrow<Rhs> {
type Output;
}
// ==================== 带借位减法实现 ====================
// ========== 带借位P1 - NonZero ==========
// P1 - I - 1 = -I
impl<I:NonZero + Neg> SubWithBorrow<I> for P1 {
type Output = I::Output;
}
// ========== 带借位N1 - NonZero ==========
// N1 - I - 1 = !I-1 (即N1+(!I+1)-1)
impl<I: NonZero + Not<Output: Sub1>> SubWithBorrow<I> for N1{
type Output = <I::Output as Sub1>::Output;
}
// ========== 带借位B0 - NonZero ==========
// B0 - P1 -1=B0
impl<H: NonZero + Sub1<Output: IfB0>> SubWithBorrow<P1> for B0<H>{
type Output = <H::Output as IfB0>::Output;
}
// B0 - N1 - 1=B0
impl<H: NonZero> SubWithBorrow<N1> for B0<H>{
type Output = Self;
}
// B0 - B0 -1=B1
impl<H1: NonZero + SubWithBorrow<H2, Output: IfB1>, H2: NonZero> SubWithBorrow<B0<H2>> for B0<H1>{
type Output = <H1::Output as IfB1>::Output;
}
// B0 - B1 -1 = B0
impl<H1: NonZero + SubWithBorrow<H2, Output: IfB0>, H2: NonZero> SubWithBorrow<B1<H2>> for B0<H1>{
type Output = <H1::Output as IfB0>::Output;
}
// ========== 带借位B1 - NonZero ==========
// B1 - P1 - 1 = B1
impl<H: NonZero + Sub1<Output: IfB1>> SubWithBorrow<P1> for B1<H>{
type Output = <H::Output as IfB1>::Output;
}
// B1 - N1 -1 = B1
impl<H: NonZero> SubWithBorrow<N1> for B1<H>
{
type Output = Self;
}
// B1 - B0 -1 = B0
impl<H1: NonZero + Sub<H2, Output: IfB0>, H2: NonZero> SubWithBorrow<B0<H2>> for B1<H1>{
type Output = <H1::Output as IfB0>::Output;
}
// B1 - B1 - 1 = B1
impl<H1: NonZero + SubWithBorrow<H2, Output: IfB1>, H2: NonZero> SubWithBorrow<B1<H2>> for B1<H1>{
type Output = <H1::Output as IfB1>::Output;
}
// ==================== 标准减法实现 (Sub trait) ====================
// ==================== Z0 - All ====================
// Z0 - I = -I
impl<I: TypedInt + Neg> Sub<I> for Z0 {
type Output = I::Output;
#[inline(always)]
fn sub(self, i: I) -> Self::Output {
-i
}
}
// Z0 - FixedPoint
impl<I: TypedInt, F: Unsigned> Sub<FixedPoint<I, F>> for Z0
where
FixedPoint<I, F>: Neg,
{
type Output = <FixedPoint<I, F> as Neg>::Output;
#[inline(always)]
fn sub(self, rhs: FixedPoint<I, F>) -> Self::Output { -rhs }
}
// Z0 - Var
impl<T: Primitive + Neg> Sub<Var<T>> for Z0 {
type Output = Var<T>;
#[inline(always)]
fn sub(self, rhs: Var<T>) -> Self::Output {
-rhs
}
}
// ========== P1 - All ==========
// P1 - I = -(I-1)
impl<I: TypedInt + Sub1<Output: Neg<Output: Default>>> Sub<I> for P1{
type Output = <I::Output as Neg>::Output;
#[inline(always)]
fn sub(self, _: I) -> Self::Output {
Default::default()
}
}
// P1 - FixedPoint
impl<I: TypedInt, F: Unsigned> Sub<FixedPoint<I, F>> for P1
where
P1: Sub<I>,
{
type Output = FixedPoint< <P1 as Sub<I>>::Output, F>;
#[inline(always)]
fn sub(self, _: FixedPoint<I, F>) -> Self::Output {
Default::default()
}
}
// P1 - Var
impl<T: Primitive> Sub<Var<T>> for P1
where
Var<T>: From<P1>,
{
type Output = Var<T>;
#[inline(always)]
fn sub(self, rhs: Var<T>) -> Self::Output {
Var::<T>::from(self) - rhs
}
}
// ========== N1 - All ==========
// N1 - I = N1 + (!I + 1)= !I
impl<I: TypedInt + Not<Output: Default>> Sub<I> for N1{
type Output = I::Output;
#[inline(always)]
fn sub(self, _: I) -> Self::Output {
Default::default()
}
}
// N1 - FixedPoint=(-FixedPoint) - 1
impl<I: TypedInt, F: Unsigned> Sub<FixedPoint<I, F>> for N1
where
FixedPoint<I, F>: Neg<Output: Sub1>,
{
type Output = < <FixedPoint<I, F> as Neg>::Output as Sub1 >::Output;
#[inline(always)]
fn sub(self, _: FixedPoint<I, F>) -> Self::Output {
Default::default()
}
}
// N1 - Var
impl<T: Primitive> Sub<Var<T>> for N1
where
Var<T>: From<N1> + Sub,
{
type Output = <Var<T> as Sub>::Output;
#[inline(always)]
fn sub(self, rhs: Var<T>) -> Self::Output {
Var::<T>::from(self) - rhs
}
}
// ========== B0 - All ==========
// B0 - Z0
impl<H: NonZero> Sub<Z0> for B0<H> {
type Output = Self;
#[inline(always)]
fn sub(self, _: Z0) -> Self::Output {
self
}
}
// B0 - P1=B0 -1
impl<H: NonZero> Sub<P1> for B0<H>
where
B0<H>:Sub1,
{
type Output = <B0<H> as Sub1>::Output;
#[inline(always)]
fn sub(self, _: P1) -> Self::Output {
Default::default()
}
}
// B0 - N1 =B0 + 1
impl<H: NonZero> Sub<N1> for B0<H>
where
B0<H>:Add1,
{
type Output = <B0<H> as Add1>::Output;
#[inline(always)]
fn sub(self, _: N1) -> Self::Output {
Default::default()
}
}
// B0 - B0 = B0
impl<H1: NonZero + Sub<H2, Output: IfB0>, H2: NonZero> Sub<B0<H2>> for B0<H1>{
type Output = <H1::Output as IfB0>::Output;
#[inline(always)]
fn sub(self, _: B0<H2>) -> Self::Output {
Default::default()
}
}
// B0 - B1 = B1
impl<H1: NonZero + SubWithBorrow<H2, Output: IfB1>, H2: NonZero> Sub<B1<H2>> for B0<H1>{
type Output = <H1::Output as IfB1>::Output;
#[inline(always)]
fn sub(self, _: B1<H2>) -> Self::Output {
Default::default()
}
}
// B0 - FixedPoint= B0 + (- FixedPoint)
impl<H: NonZero, I: TypedInt, F: Unsigned> Sub<FixedPoint<I, F>> for B0<H>
where
FixedPoint<I, F>: Neg,
Self: Sub< <FixedPoint<I, F> as Neg>::Output, Output: Default >,
{
type Output = < Self as Sub< <FixedPoint<I, F> as Neg>::Output> >::Output;
#[inline(always)]
fn sub(self, _: FixedPoint<I, F>) -> Self::Output {
Default::default()
}
}
// B0 - Var
impl<T: Primitive, H: NonZero> Sub<Var<T>> for B0<H>
where
Var<T>: From<B0<H>>,
{
type Output = <Var<T> as Sub>::Output;
#[inline(always)]
fn sub(self, rhs: Var<T>) -> Self::Output {
Var::<T>::from(self) - rhs
}
}
// ========== B1 - All ==========
// B1-Z0
impl<H: NonZero> Sub<Z0> for B1<H> {
type Output = Self;
#[inline(always)]
fn sub(self, _: Z0) -> Self::Output {
self
}
}
// B1 - P1 = B1 - 1
impl<H: NonZero> Sub<P1> for B1<H>
where
B1<H>: Sub1,
{
type Output = <B1<H> as Sub1>::Output;
#[inline(always)]
fn sub(self, _: P1) -> Self::Output {
Default::default()
}
}
// B1 - N1 = B1 + 1
impl<H: NonZero + Add1> Sub<N1> for B1<H>
where
B1<H>: Add1,
{
type Output = <B1<H> as Add1>::Output;
#[inline(always)]
fn sub(self, _: N1) -> Self::Output {
Default::default()
}
}
// B1 - B0 = B1
impl<H1: NonZero + Sub<H2,Output: IfB1>, H2: NonZero> Sub<B0<H2>> for B1<H1>{
type Output = <H1::Output as IfB1>::Output;
#[inline(always)]
fn sub(self, _: B0<H2>) -> Self::Output {
Default::default()
}
}
// B1 - B1 = B0
impl<H1: NonZero + Sub<H2,Output: IfB0>, H2: NonZero> Sub<B1<H2>> for B1<H1>{
type Output = <H1::Output as IfB0>::Output;
#[inline(always)]
fn sub(self, _: B1<H2>) -> Self::Output {
Default::default()
}
}
// B1 - FixedPoint = B1 + (-FixedPoint)
impl<H: NonZero, I: TypedInt, F: Unsigned> Sub<FixedPoint<I, F>> for B1<H>
where
FixedPoint<I, F>: Neg,
Self: Sub< <FixedPoint<I, F> as Neg>::Output, Output: Default >,
{
type Output = <Self as Sub< <FixedPoint<I, F> as Neg>::Output > >::Output;
#[inline(always)]
fn sub(self, _: FixedPoint<I, F>) -> Self::Output {
Default::default()
}
}
// B1 - Var
impl<T: Primitive, H: NonZero> Sub<Var<T>> for B1<H>
where
Var<T>: From<B1<H>>,
{
type Output = <Var<T> as Sub>::Output;
#[inline(always)]
fn sub(self, rhs: Var<T>) -> Self::Output {
Var::<T>::from(self) - rhs
}
}
// ==================== FixedPoint - All ====================
// FixedPoint -I2
impl<I: TypedInt + Sub<I2>, F: Unsigned, I2: TypedInt> Sub<I2> for FixedPoint<I, F>{
type Output = FixedPoint< <I as Sub<I2>>::Output, F>;
#[inline(always)]
fn sub(self, _: I2) -> Self::Output {
Default::default()
}
}
// FixedPoint - FixedPoint=FixedPoint + (-FixedPoint)
impl<I1: TypedInt, F1: Unsigned, I2: TypedInt, F2: Unsigned> Sub<FixedPoint<I2, F2>> for FixedPoint<I1, F1>
where
FixedPoint<I2, F2>: Neg,
Self: Add<<FixedPoint<I2, F2> as Neg>::Output>
{
type Output = < Self as Add<<FixedPoint<I2, F2> as Neg>::Output> >::Output;
#[inline(always)]
fn sub(self, rhs: FixedPoint<I2, F2>) -> Self::Output {
self + (-rhs)
}
}
// FixedPoint -Var
impl<T: Primitive, I: TypedInt, F: Unsigned> Sub<Var<T>> for FixedPoint<I, F>
where
Var<T>: Sub + From<Self>,
{
type Output = <Var<T> as Sub>::Output;
#[inline(always)]
fn sub(self, rhs: Var<T>) -> Self::Output {
Var::<T>::from(self) - rhs
}
}
// ==================== Var - All ====================
// Var - I
impl<T: Primitive, I: TypedInt> Sub<I> for Var<T>
where
Var<T>: From<I> + Sub,
{
type Output = <Var<T> as Sub>::Output;
#[inline(always)]
fn sub(self, rhs: I) -> Self::Output {
self - Var::<T>::from(rhs)
}
}
// Var - FixedPoint,需要完善 FixedPoint => Var
impl<T: Primitive, I: TypedInt, F: Unsigned> Sub<FixedPoint<I, F>> for Var<T>
where
Self: From<FixedPoint<I, F>>,
{
type Output = <Self as Sub>::Output;
#[inline(always)]
fn sub(self, rhs: FixedPoint<I, F>) -> Self::Output {
self - Var::<T>::from(rhs)
}
}
/// 实现 Var 与 Var 的减法运算
/// 用法: V - V
impl<T: Primitive> Sub for Var<T> {
type Output = Self;
fn sub(self, b: Self) -> Self::Output {
Var(self.0 - b.0) // 内部值相减后包装为新 Var
}
}
#[cfg(test)]
mod tests {
use crate::number::*;
// ==================== 标准减法测试 ====================
#[test]
fn test_z0_sub() {
// Z0 - I
assert_eq!(Z0 - P1, N1);
assert_eq!(Z0 - N1, P1);
assert_eq!(Z0 - B0::<P1>::default(), B0::<N1>::default());
// Z0 - FixedPoint
assert_eq!(
Z0 - FixedPoint::<P1, B0<B0<P1>>>::default(),
FixedPoint::< B0<N1>, B1<B1<P1>> >::default()
);
// Z0 - Var
let var = Var(5i32);
assert_eq!(Z0 - var, Var(-5i32));
}
#[test]
fn test_p1_sub() {
// P1 - I
assert_eq!(P1 - P1, Z0);
assert_eq!(P1 - N1, B0::<P1>::default());
assert_eq!(P1 - B0::<P1>::default(), N1);
// P1 - FixedPoint
assert_eq!(
P1 - FixedPoint::<P1, B0<B0<B0<P1>>>>::default(),
FixedPoint::<Z0, B0<B0<B0<P1>>>>::default()
);
// P1 - Var
let var = Var(2i32);
assert_eq!(P1 - var, Var(-1i32));
}
#[test]
fn test_n1_sub() {
// N1 - I
assert_eq!(N1 - P1, B0::<N1>::default());
assert_eq!(N1 - N1, Z0);
assert_eq!(N1 - B0::<P1>::default(), B1::<B0<N1>>::default());
// N1 - FixedPoint
assert_eq!(
N1 - FixedPoint::<P1, B0<B0<B0<P1>>>>::default(),
FixedPoint::<B0<N1>, B1<B1<B1<P1>>>>::default()
);
// N1 - Var
let var = Var(3i32);
assert_eq!(N1 - var, Var(-4i32));
}
#[test]
fn test_b0_sub() {
// B0 - I
assert_eq!(B0::<P1>::default() - Z0, B0::<P1>::default());
assert_eq!(B0::<P1>::default() - P1, B0::<Z0>::default());
assert_eq!(B0::<P1>::default() - N1, B1::<P1>::default());
assert_eq!(B0::<B0<P1>>::default() - B0::<P1>::default(), B0::<P1>::default());
assert_eq!(B0::<B0<P1>>::default() - B1::<P1>::default(), P1);
// B0 - FixedPoint
assert_eq!(
B0::<P1>::default() - FixedPoint::<P1, B0<B0<B0<P1>>>>::default(),
FixedPoint::<B0::<Z0>, B0<B0<B0<P1>>>>::default()
);
// B0 - Var
let var = Var(3i32);
assert_eq!(B0::<P1>::default() - var, Var(-3i32));
}
#[test]
fn test_b1_sub() {
// B1 - I
assert_eq!(B1::<P1>::default() - Z0, B1::<P1>::default());
assert_eq!(B1::<P1>::default() - P1, P1);
assert_eq!(B1::<P1>::default() - N1, B0::<B0<P1>>::default());
assert_eq!(B1::<B0<P1>>::default() - B0::<P1>::default(), B1::<P1>::default());
assert_eq!(B1::<B0<P1>>::default() - B1::<P1>::default(), B0::<P1>::default());
// B1 - FixedPoint
assert_eq!(
B1::<P1>::default() - FixedPoint::<P1, B0<B0<P1>>>::default(),
FixedPoint::<B1::<Z0>, B0<B0<P1>>>::default()
);
// B1 - Var
let var = Var(2i32);
assert_eq!(B1::<P1>::default() - var, Var(-1i32));
}
#[test]
fn test_fixed_point_sub() {
// FixedPoint - I
assert_eq!(
FixedPoint::<B0<P1>, B0<B0<B0<P1>>>>::default() - P1,
FixedPoint::<P1, B0<B0<B0<P1>>>>::default()
);
// FixedPoint - FixedPoint
let fp1 = FixedPoint::<P1, B0<B0<B0<P1>>>>::default();
let fp2 = FixedPoint::<P1, B0<B0<B0<P1>>>>::default();
assert_eq!(fp1 - fp2, FixedPoint::<Z0, Z0>::default());
// FixedPoint - Var
let var = Var(1i32);
assert_eq!(
FixedPoint::<P1, B0<B0<B0<P1>>>>::default() - var,
Var(0i32)
);
}
#[test]
fn test_var_sub() {
// Var - I
let var = Var(5i32);
assert_eq!(var - P1, Var(4i32));
// Var - FixedPoint
let fp = FixedPoint::<P1, B0<B0<B0<P1>>>>::default();
assert_eq!(Var(3i32) - fp, Var(2i32));
// Var - Var
let var1 = Var(5i32);
let var2 = Var(3i32);
assert_eq!(var1 - var2, Var(2i32));
}
}
SubWithBorrow: 带借位的减法 trait,表示 a - b - 1 的运算
Sub: 标准减法 trait 的实现
数字类型:
Z0: 表示零
P1: 表示 +1
N1: 表示 -1
B0, B1: 二进制数表示(H 是高位)
FixedPoint: 定点数(I 是整数部分,F 是小数部分)
Var: 运行时变量(T 是基本类型如 i32)
处理各种类型组合的带借位减法(a - b - 1):
P1 - NonZero: 结果为 -I
N1 - NonZero: 结果为 !I - 1
B0 与各种类型的减法
B1 与各种类型的减法
为各种类型组合实现标准减法:
Z0 - All: 零减任何数等于其相反数
P1 - All: +1 减其他数
N1 - All: -1 减其他数
B0 - All: 二进制数 0… 减其他数
B1 - All: 二进制数 1… 减其他数
FixedPoint - All: 定点数减法
Var - All: 运行时变量减法
包含对各种减法情况的测试,验证实现的正确性。
类型安全计算: 所有运算都在类型系统层面完成,保证编译期类型安全
零成本抽象: 运行时没有额外开销
组合式设计: 通过 traits 和关联类型组合各种运算
扩展性: 可以方便地添加新的数字类型和运算
// 编译期计算
let _ = Z0 - P1; // 结果为 N1 (-1)
let _ = B0<P1> - B1<P1>; // 二进制数运算
// 运行时变量计算
let var = Var(5i32);
let result = var - P1; // 结果为 Var(4i32)
这段代码展示了 Rust 类型系统的强大能力,能够在编译期完成复杂的数值计算和类型转换,同时保持类型安全和零成本抽象。