一、源码
这段代码是用Rust语言实现的一个类型系统级别的算术取负运算(-运算符),通过Rust的特性(trait)系统来实现。
rust
use core::ops::{Not, Neg};
use crate::number::{Z0, P1, N1, B0, B1, NonZero, Float, Var, PrimitiveInt, Primitive};
// ==================== 算术取负(-运算符) ====================
impl Neg for Z0 { // Z0 (0) 的取负
type Output = Z0;
fn neg(self) -> Self::Output {
Z0
}
}
impl Neg for P1 {
type Output = N1;
fn neg(self) -> Self::Output {
N1
}
}
impl Neg for N1 { // N1 (-1) 的取负,用P1替换B1<Z0>
type Output = P1;
fn neg(self) -> Self::Output {
P1
}
}
impl<H: NonZero + Neg> Neg for B0<H>{
type Output = B0<H::Output>;
fn neg(self) -> Self::Output {
B0::new()
}
}
impl<H: NonZero + Not> Neg for B1<H>{
type Output = B1<H::Output>;
fn neg(self) -> Self::Output {
B1::new()
}
}
// 浮点数取反
impl<Mantissa: Neg, Exponent> Neg for Float<Mantissa, Exponent> {
type Output = Float<Mantissa::Output, Exponent>;
fn neg(self) -> Self::Output {
Float::new()
}
}
// -Var<T> = Var<-T>
impl<T: Primitive + Neg> Neg for Var<T> {
type Output = Var<<T as Neg>::Output>;
#[inline(always)]
fn neg(self) -> Self::Output {
Var(-self.0)
}
}
二、源码分析
- 导入依赖
rust
use core::ops::{Not, Neg};
use crate::number::{Z0, P1, N1, B0, B1, NonZero, Float, Var, PrimitiveInt, Primitive};
-
Neg trait:这是Rust标准库中的算术取负运算符trait。
-
Not trait:这是Rust标准库中的位取反运算符trait(虽然这里主要用Neg,但Not可能在其他地方用到)。
-
其他类型(Z0, P1, N1, B0, B1, Float, Var等)是自定义的类型,用于表示不同的数字或数值。
- 基础类型实现
这部分实现了基本数字类型的算术取负运算。
a. 零取负
rust
impl Neg for Z0 { // Z0 (0) 的取负
type Output = Z0;
fn neg(self) -> Self::Output {
Z0
}
}
-
Z0表示数字0。
-
算术取负运算-0的结果仍然是0(用Z0表示)。
b. 正一取负
rust
impl Neg for P1 {
type Output = N1;
fn neg(self) -> Self::Output {
N1
}
}
-
P1表示数字1。
-
算术取负运算-1的结果是-1(用N1表示)。
c. 负一取负
rust
impl Neg for N1 { // N1 (-1) 的取负,用P1替换B1<Z0>
type Output = P1;
fn neg(self) -> Self::Output {
P1
}
}
-
N1表示数字-1。
-
算术取负运算-(-1)的结果是1(用P1表示)。
- 递归类型实现
这部分处理二进制数的算术取负,通过递归的方式处理更高位的二进制数。
a. 二进制0前缀取负
rust
impl<H: NonZero + Neg> Neg for B0<H>{
type Output = B0<H::Output>;
fn neg(self) -> Self::Output {
B0::new()
}
}
- B0表示一个以0为前缀的二进制数(例如B0表示10,即-2)。
取负后变为B0<-H>(即前缀0保持不变,剩余部分取负)。
b. 二进制1前缀取负
rust
impl<H: NonZero + Not> Neg for B1<H>{
type Output = B1<H::Output>;
fn neg(self) -> Self::Output {
B1::new()
}
}
-
B1表示一个以1为前缀的二进制数(例如B1表示01,即1)。
-
取负后变为B1<!H>(即前缀1保持不变,剩余部分取反,这里用Not可能是为了优化或特殊处理)。
- 浮点数取负
rust
impl<Mantissa: Neg, Exponent> Neg for Float<Mantissa, Exponent> {
type Output = Float<Mantissa::Output, Exponent>;
fn neg(self) -> Self::Output {
Float::new()
}
}
-
Float<Mantissa, Exponent>表示一个浮点数,由尾数(Mantissa)和指数(Exponent)组成。
-
取负运算只对尾数部分取负,指数部分保持不变。
- 变量类型取负
rust
impl<T: Primitive + Neg> Neg for Var<T> {
type Output = Var<<T as Neg>::Output>;
#[inline(always)]
fn neg(self) -> Self::Output {
Var(-self.0)
}
}
-
Var是一个包装类型,用于表示变量。
-
如果T实现了Neg,则Var也可以进行算术取负运算,结果为Var<-T>。
三、总结
这段代码实现了一个类型级别的算术取负运算系统,支持:
-
基本数字(0、1、-1)的取负。
-
二进制数的递归取负(B0和B1)。
-
浮点数的取负(只对尾数取负)。
-
变量类型的取负。
这种技术常用于类型安全的数学库或嵌入式DSL(领域特定语言)中,确保编译期就能完成某些计算或检查。