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

用Rust写平衡三进制加法器

1、三进制加法器的发展

        最初的平衡三进制加法是采用了三选一结构(github原文),这位大佬也很厉害,他是硬件都弄了出来的,也写了虚拟机,甚至用这三态多路复用器弄出了可以存状态的硬件,但我没有去看了,因为当初刚开始的的一个全加器的方案(详情),都看了几天才懂,实在是不想费脑子了;不过也告诉我平衡三进制加法器确实存在,再后来,用图灵完备模拟了这结构,结果发现太复杂了,单1个零部件都好麻烦,然后幸运的推理出了与二进制相似的结构,即用2个平衡三进制半加器及1个平衡三进制调和门组成一器,哪时感觉牛呀;又后面,尝试用c++写这虚拟机,写着写着感觉很麻烦,就没写了,改用了rust来写,rust的好处就是它的变量是默认不会变的,写出来加法器后,在我眼中,数组就是平衡三进制逻辑门,平衡三进制就是数组,有关请看:平衡三进制存算一体架构


2、平衡三进制的二进制编码

        转来转去的,目前最好实现的还是二进制,你想一下,一辆车走一条马路与两辆车走同一条马路并驱,速度是不是一样快,用空间来换时间还是很好用的,所以编码用来用去,还是方案二好用,如下所示:

二进制编码平衡三进制表示十进制
0000
0111
10T2
11未使用未使用

3、平衡三进制逻辑门的转换

        在上面用了2bit表示1trit,写虚拟机时发现8bit就是计算机的通用程序最小单位了,最主要的是它的移植性,所以都以1byte表示1trit,然后就是2表示的是-1、0表示0、1表示1,为什么这样映射,因为数组是从0开始的,不能以-1开始,然后这样就可以,将平衡三进制逻辑门进成数组的形式,而下图的三种逻辑门,就是组成全加器的关键,我们可以尝试转换。

例如,转换加和门:

逻辑加和012
0012
1120
2201

4、平衡三进制逻辑门的使用

        现在的你,已经可以将数组变成逻辑门来使用了,所以我们尝试用rust,目标是写一个平衡三进制的多位加法器,先用1个加和门与1个共识门,组成1个平衡三进制半加器,然后再用2平衡三进制半加器和1个调和门,组成1个平衡三进制全加器,最后由多个全加器组成多位加法器;当然,这里是编程,我们只用到一个全加器,然后用while循环处理多位就好了,代码如下:

// **加和(TSUM)逻辑表 当为TT、01、10时出1,当为11、0T、T0时出T,其余为0 此门用于半加器的加和位处理 **
const TSUM:[[u8; 3];3]= [[0, 1, 2],[1, 2, 0],[2, 0, 1],
];
// **共识(TCONS)逻辑表 双T出T、双1出1、其余为0 此门用于半加器的进位处理 **
const TCONS:[[u8; 3];3]= [[0, 0, 0],[0, 1, 0],[0, 0, 2],
];
// **调和(TANY)逻辑表 当为TT、0T、T0时出T,当为11、01、10时出1,其余为0 此门用于全加器进位处理 **
const TANY:[[u8; 3];3]= [[0, 1, 2],[1, 1, 0],[2, 0, 2],
];/// 半加器:返回 (sum, carry)
pub fn ternary_half_adder(a: u8, b: u8) -> (u8, u8) {let sum = TSUM[a as usize][b as usize];// 和let carry=TCONS[a as usize][b as usize];// 进位;(sum, carry)
}
/// 全加器2:基于半加器实现
pub fn ternary_full_adder(a: u8, b: u8, c_in: u8) -> (u8, u8) {//2个平衡三进制半加器及1个平衡三进制调和门,组成一个平衡三进制全加器let (num,c1_in)=ternary_half_adder(a,b);let (sum,c2_in)=ternary_half_adder(num,c_in);let carry=TANY[c1_in as usize][c2_in as usize];//两个进位数合成一个进位数;(sum, carry)
}fn main() {let a = 1;let b = 1;let c=1;let (sum,carry)=ternary_half_adder(a, b);//半加器let (sum2,carry2)=ternary_full_adder(a, b, c);//平衡全加器println!("平衡半加器 sum:{} carry:{}",sum,carry);println!("平衡全加器 sum:{} carry:{}",sum2,carry2);
}

如上图所示,1+1=1T、1+1+1=10,运行结果也很正确。


5、平衡三进制多位加法器

        其实上面的程序,可以更加简化,都已经将数组用成的逻辑门了,所以可以不用加和门、共识门、调和门什么的,直接面向结果编程,就像九九乘法表,所以用它的真值表,来写两个三维数组保存它的结果,直接调用这样就可以极大提升效率,平衡三进制全加真值表,如下所示:

所以就可以写出,如下代码:

// **全加器和(TFULLSUM) 逻辑表**
const TFULLSUM:[[[u8; 3];3];3] = [[[0, 1, 2],[1, 2, 0],[2, 0, 1],],[[1, 2, 0],[2, 0, 1],[0, 1, 2],],[[2, 0, 1],[0, 1, 2],[1, 2, 0],],
];
// **全加器进位(TFULLCONS) 逻辑表**
const TFULLCONS:[[[u8; 3];3];3] = [[[0, 0, 0],[0, 1, 0],[0, 0, 2],],[[0, 1, 0],[1, 1, 0],[0, 0, 0],],[[0, 0, 2],[0, 0, 0],[2, 0, 2],],
];/// 全加器:基于三维数组实现
pub fn ternary_full_adder(a: u8, b: u8, c_in: u8) -> (u8, u8) {let sum =TFULLSUM[a as usize][b as usize][c_in as usize];// 和let carry=TFULLCONS[a as usize][b as usize][c_in as usize];// 进位(sum, carry)
}fn main() {let a = 1;let b = 1;let c=1;let (sum2,carry2)=ternary_full_adder(a, b, c);//平衡全加器println!("平衡全加器 sum:{} carry:{}",sum2,carry2);}

        结果正确,最后就多位相加的问题了,刚开始我也是想用for循环处理的,但太麻烦了,要用迭代器什么的,还要判断是否长度一样,它又是从低位加到高位的,所以我想很久,让我想到了一个优雅的方案--栈,栈这数据结构是先进后出,这样一个数如:1234与567,存入后再弹出就是4321与765,所以只要有两个栈协同弹出,先栈空的换成0,直到两栈都为空就完成了运算,巧的是,Rust标准库中Vec,天然就支持后进先出(LIFO),所以就可以写出,如下代码:

// **全加器和(TFULLSUM) 逻辑表**
const TFULLSUM:[[[u8; 3];3];3] = [[[0, 1, 2],[1, 2, 0],[2, 0, 1],],[[1, 2, 0],[2, 0, 1],[0, 1, 2],],[[2, 0, 1],[0, 1, 2],[1, 2, 0],],
];
// **全加器进位(TFULLCONS) 逻辑表**
const TFULLCONS:[[[u8; 3];3];3] = [[[0, 0, 0],[0, 1, 0],[0, 0, 2],],[[0, 1, 0],[1, 1, 0],[0, 0, 0],],[[0, 0, 2],[0, 0, 0],[2, 0, 2],],
];/// 全加器:基于三维数组实现
pub fn ternary_full_adder(a: u8, b: u8, c_in: u8) -> (u8, u8) {let sum =TFULLSUM[a as usize][b as usize][c_in as usize];// 和let carry=TFULLCONS[a as usize][b as usize][c_in as usize];// 进位(sum, carry)
}///多位三进制加法器基础,输入两个的三进制向量,返回加法结果向量和最终进位
pub fn ternary_stackadder_base(mut stack1: Vec<u8>,mut stack2: Vec<u8>,carry_in: u8)-> (Vec<u8>, u8){let mut result:Vec<u8> = Vec::new();//存储和let mut c_in:u8=carry_in;//Rust标准库中Vec,天然支持后进先出(LIFO),用栈协同弹出,倒序遍历, 支持不同长度while !stack1.is_empty() || !stack2.is_empty() {let v1 = stack1.pop().unwrap_or(0);let v2 = stack2.pop().unwrap_or(0);let (s_out, next_carry) =ternary_full_adder(v1, v2, c_in);result.push(s_out);//存结果c_in=next_carry;//进位传递}//result.push(c_in);可选,最高位溢出推入result.reverse(); // 反转,从高位到低位排列(result, c_in)
}//多位三进制加法器
pub fn ternary_stack_adder(stack1: Vec<u8>,stack2: Vec<u8>) -> Vec<u8> {let (mut result, carry) = ternary_stackadder_base(stack1,stack2, 0);result.insert(0, carry);result
}fn main() {let stack1=vec![0,1,1,1];let stack2=vec![0,2,0,0];let c:u8=1;let (sum,carry)=ternary_stackadder_base(stack1, stack2, c);println!("结果{}{:?}",carry,sum);}

结果正确,完结,撒花。。


6、平衡三进制逻辑门大全

        数组就是逻辑门,算的快不如转的快,感觉忆阻器是很有前途,阻值没有负数,但是有0、1、2,这就已经够用了,不行还可以用,二位bit模拟1位平衡三进制数,管它那么多,先造出来再说,以下是平衡三进制的数组逻辑门大全,代码如下所示:

///*三进制逻辑门查找表声明**
///*2025/5/29**
///
///  平衡三进制摩根定律及逻辑门转换图
///        TOR  <------->  TNOR
///         ^               ^
///         |               |
///         |               |
///         v               v
///       TNAND <------->  TAND// **非门(TNEG)逻辑表 输入T,输出1;输入0,输出0;输入1,输出T;**
pub const TNEG:[u8; 3]= [0, 2, 1];
// **右偏门(RIGHT_MUX)逻辑表(A+1) 输入T,输出0;输入0,输出1;输入1,输出T;**
pub const RIGHT_MUX:[u8; 3]= [1, 2, 0];
// **左偏门(LEFT_MUX)逻辑表(A-1)  输入T,输出1;输入0,输出T;输入1,输出0;**
pub const LEFT_MUX: [u8; 3]= [2, 0, 1];
// **最大门(MAX_MUX)逻辑表max(A,0) A与0比较,较大的输出 **
pub const MAX_MUX:[u8; 3]= [0, 1, 0];
// **最小门(MIN_MUX)逻辑表min(A,0) A与0比较,较小的输出 **
pub const MIN_MUX:[u8; 3]= [0, 0, 2];// **或门(TOR)逻辑表MAX(A,B) 有1出1、双T出T、其余为0 **
pub const TOR:[[u8; 3];3]= [[0, 1, 0],[1, 1, 1],[0, 1, 2],
];
// **与门(TAND)逻辑表MIN(A,B) 有T出T、双1出1、其余为0 **
pub const TAND:[[u8; 3];3]= [[0, 0, 2],[0, 1, 2],[2, 2, 2],
];
// **或非门(TNOR)逻辑表 有1出T、双T出1、其余为0 **
pub const TNOR:[[u8; 3];3]= [[0, 2, 0],[2, 2, 2],[0, 2, 1],
];
// **与非门(TAND)逻辑表 有T出1、双1出T、其余为0 **
pub const TNAND:[[u8; 3];3]= [[0, 0, 1],[0, 2, 1],[1, 1, 1],
];
// **异或门(TXOR)逻辑表 双T及双1出T、1T及T1出1、其余为0 **
pub const TXOR:[[u8; 3];3]= [[0, 0, 0],[0, 2, 1],[0, 1, 2],
];
// **同或门(TXNOR)逻辑表 双T及双1出1、1T及T1出T、其余为0 **
pub const TXNOR:[[u8; 3];3]= [[0, 0, 0],[0, 1, 2],[0, 2, 1],
];// **加和(TSUM)逻辑表 当为TT、01、10时出1,当为11、0T、T0时出T,其余为0 此门用于半加器的加和位处理 **
pub const TSUM:[[u8; 3];3]= [[0, 1, 2],[1, 2, 0],[2, 0, 1],
];
// **共识(TCONS)逻辑表 双T出T、双1出1、其余为0 此门用于半加器的进位处理 **
pub const TCONS:[[u8; 3];3]= [[0, 0, 0],[0, 1, 0],[0, 0, 2],
];
// **调和(TANY)逻辑表 当为TT、0T、T0时出T,当为11、01、10时出1,其余为0 此门用于全加器进位处理 **
pub const TANY:[[u8; 3];3]= [[0, 1, 2],[1, 1, 0],[2, 0, 2],
];// **全加器和(TFULLSUM) 逻辑表**
pub const TFULLSUM:[[[u8; 3];3];3] = [[[0, 1, 2],[1, 2, 0],[2, 0, 1],],[[1, 2, 0],[2, 0, 1],[0, 1, 2],],[[2, 0, 1],[0, 1, 2],[1, 2, 0],],
];
// **全加器进位(TFULLCONS) 逻辑表**
pub const TFULLCONS:[[[u8; 3];3];3] = [[[0, 0, 0],[0, 1, 0],[0, 0, 2],],[[0, 1, 0],[1, 1, 0],[0, 0, 0],],[[0, 0, 2],[0, 0, 0],[2, 0, 2],],
];
// **三与门(T3AND)逻辑表 有T出T、三1出1、其余为0 **
pub const T3AND:[[[u8; 3];3];3] = [[[0, 0, 2],[0, 0, 2],[2, 2, 2],],[[0, 0, 2],[0, 1, 2],[2, 2, 2],],[[2, 2, 2],[2, 2, 2],[2, 2, 2],],
];
// **三或门(T3AND)逻辑表 有1出1、三T出T、其余为0 **
pub const T3OR:[[[u8; 3];3];3] = [[[0, 1, 0],[1, 1, 1],[0, 1, 0],],[[1, 1, 1],[1, 1, 1],[1, 1, 1],],[[0, 1, 0],[1, 1, 1],[0, 1, 2],],
];

相关文章:

  • 哪个网站做的效果图好网上做广告宣传
  • 南京直销网站开发吉林网站推广公司
  • 网站公司注册流程sem分析是什么
  • 做公众号微网站2022年可以打开的网址
  • 乐清建设路小学校园网站seo标题优化裤子关键词
  • APP加网站建设预算多少钱阿里云域名查询和注册
  • 华为云Flexus+DeepSeek征文|基于华为云Flexus Dify复用优秀 AI Agent 应用教程
  • TMS汽车热管理系统HILRCP解决方案
  • FastMCP+python简单测试
  • Jenkins+Jmeter+Ant接口持续集成
  • 信创建设,如何统一管理异构服务器的认证、密码、权限管理等?
  • 配置自己的NTP 服务器做时间同步
  • 从零学习linux(2)——管理
  • 缺少 XML 验证与资源注入修复
  • Revisiting Image Deblurring with an Efficient ConvNet论文阅读
  • Joblib库多进程/线程使用(一):使用generator参数实现边响应边使用
  • leetcode61.旋转链表
  • 物流业最后的“人工堡垒”即将失守?机器人正式接管卡车装卸工作
  • java数据类型详解篇
  • 【机器学习深度学习】机器学习核心概念图谱:样本、目标函数、损失函数、特征及训练
  • 【源码】Reactive 源码
  • 【CS创世SD NAND征文】基于全志V3S与CS创世SD NAND的物联网智能路灯网关数据存储方案
  • 闲庭信步使用SV搭建图像测试平台:第九课——初步使用类
  • 开疆智能CCLinkIE转ModbusTCP网关连接施耐德TCP从站配置案例
  • NEO4j的安装部署
  • P0/P1级重大故障根因分析:技术挑战与无指责复盘文化