用Rust寫平衡三進制乘法器

1、平衡三進制乘法表

????????前面寫了平衡三進制的加法器,這個乘法器是在這基礎上的,沒看過的可以回去看看,說到乘法器還是要參考前蘇聯的資料的,平衡三進制的乘法也是很方便的,在平衡三進制基礎中有詳細講過,下圖就是資料:

? ? ? ? 也就是有(-1/0/1)這三相數互相相乘,結果得到的還是(-1/0/1),所以是很方便的,你認真看這乘法表其實就是邏輯表中的同或門(零乘任何數都為0,然后1*1與T*T結果都為1、最后是T*1或是1*T結果都為T),所以平衡三進制同或門等同于乘法表。


2、平衡三進制2位乘法器

????????這平衡三進制的乘法器,與二進制結構差不太多,也就是從低位到高位,依次相乘后相加與我們人類的計算一樣,只過用一個用的是二進制,另一個用的是平衡三進制,原理結構圖,如下所示:

? ? ? ? 用上面的思路,即AB*CD,得AC*100+10*(AD+BC)+BD,這三部分在不同的位置上,同或門完成的是AC相乘的結果,就是1位相乘的結果,它結果就是1trit,所以很有優勢,也是只要半加器相加就可以,這樣就可以寫出,如下代碼:

// **加和(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],
];
// **同或門(TXNOR)邏輯表 雙T及雙1出1、1T及T1出T、其余為0 此門相當于乘法表用于相乘處理 **
pub const TXNOR:[[u8; 3];3]= [[0, 0, 0],[0, 1, 2],[0, 2, 1],
];/// 半加器:返回 (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)
}
/// 全加器:基于半加器實現
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)
}
/// 2位乘法器
pub fn ternary_2trit_mul(a: u8, b: u8, c:u8, d:u8) -> (u8, u8,u8,u8) {//2個平衡三進制同或門及1個平衡三進制調和門,組成一個平衡三進制全加器let ac=TXNOR[a as usize][c as usize];let ad=TXNOR[a as usize][d as usize];let bc=TXNOR[b as usize][c as usize];let bd=TXNOR[b as usize][d as usize];let (num,carry)=ternary_half_adder(ad, bc);let (num2,carry2)=ternary_half_adder(ac, carry);(carry2,num2,num,bd)
}///多位三進制加法器基礎,輸入兩個的三進制向量,返回加法結果向量和最終進位
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() {println!("結果{:?}",ternary_2trit_mul(1, 2, 2, 0));//1T(2)*T0(-3)=0T10(-9+3=-6)println!("結果{:?}",ternary_2trit_mul(2, 2, 1, 2));//TT(-4)*1T(2)=0T01(-9+1=-8)println!("結果{:?}",ternary_2trit_mul(1, 1, 1, 1));//11(4)*11(4)=1TT1(27-9-3+1=16)
}

結果正確。


3、平衡三進制多位乘法器

? ? ? ? 在這基礎上實現多位乘法器,也是很簡單的,可以用經典的“列乘法”邏輯,也就是被乘數是固定的,每個乘數單獨相乘,得到多個部分積,最后移位后相加即可,詳情請看計算機組成原理(九):乘法器,借用一下思路,如下所示:

  A = 1101  (13 in decimal)
× B = 1011  (11 in decimal)
--------------1101   (部分積1)
+    1101    (部分積2)
+   0000     (部分積3)
+  1101      (部分積4)
--------------10001111   (143 in decimal)

也就分別得到各個部分積,這也可用于平衡三進制,得代碼如下所示:

// **全加器和(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],],
];
// **同或門(TXNOR)邏輯表 雙T及雙1出1、1T及T1出T、其余為0 此門相當于乘法表用于相乘處理 **
pub const TXNOR:[[u8; 3];3]= [[0, 0, 0],[0, 1, 2],[0, 2, 1],
];/// 全加器:基于三維數組實現
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_stack_adder(mut stack1: Vec<u8>,mut stack2: Vec<u8>)-> Vec<u8>{let mut result:Vec<u8> = Vec::new();//存儲和let mut c_in:u8=0;//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
}///多位三進制乘法器基礎
pub fn ternary_mul_base(stack1: Vec<u8>, stack2: Vec<u8>)-> Vec<u8>{let mut partials: Vec<Vec<u8>> =  Vec::new();let mut shift = 0;//將 stack2 看作乘數,從低位到高位for &m2 in stack2.iter().rev(){//將 stack1 看作被乘數,固定不動let mut partial: Vec<u8> = stack1.iter().map(|&m1| TXNOR[m1 as usize][m2 as usize]).collect();// 在尾部精確補0partial.extend(vec![0; shift]);shift += 1;partials.push(partial);}//累加所有偏移乘積let mut result = vec![0];for partial in partials {result = ternary_stack_adder(result, partial);}result
}fn main() {let stack1=vec![1,1,0,1];let stack2=vec![1,0,1,1];let re=ternary_mul_base(stack1,stack2);print!("{:?}",re);
}

結果正確,1101(十進制31)*1011(十進制31)=1TTT0111(十進制1147)。


4、平衡三進制偏積表乘法器

? ? ? ? 從上面可以得知,它是用各個部分積累計相加得到結果的,也就是說只要得到,各個偏積就能有結果,比如:

A=1101(被乘數)? ? ? ? B=1011(乘數)

1101 * 1=1101
1101 * 1=1101
1101 * 0=0000
1101 * 1=1101

所以,在平衡三進制中,有任何數0乘都得0,任何數乘1等于它本身,任何數乘T(-1)等于相反數,這樣可構建出偏積表,有沒有注意上多個部分積,只有1101與0000,它是二進制的,而對于平衡三進制它的結果有三種,即:0000、1101、2202,這個就是偏積表,用被乘數形成偏積表,乘數當成下標來調用偏積表,然后移位后相加就可以得到最后的結果,長的當被乘數好,這樣算的快,這個版本比上面的版本好,代碼如下所示:

// **全加器和(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],],
];
// **非門(TNEG)邏輯表 輸入T,輸出1;輸入0,輸出0;輸入1,輸出T;**
const TNEG:[u8; 3]= [0, 2, 1];/// 全加器:基于三維數組實現
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_stack_adder(mut stack1: Vec<u8>,mut stack2: Vec<u8>)-> Vec<u8>{let mut result:Vec<u8> = Vec::new();//存儲和let mut c_in:u8=0;//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
}///多位三進制乘法器基礎
pub fn ternary_mul_base(stack1: Vec<u8>, stack2: Vec<u8>)-> Vec<u8>{let partial_t: Vec<u8> = stack1.iter().map(|&m| TNEG[m as usize]).collect();// 構建偏積表:分別是乘以 0, 1, T 的情況let partials = vec![vec![0; stack1.len()], //0乘任何數,都得0stack1.clone(),        //任何數乘1,等于它本身partial_t,             //任何數乘T(-1)等于相反數];let mut result: Vec<u8> = vec![0];for (shift, &m2) in stack2.iter().rev().enumerate() {let mut part = partials[m2 as usize].clone();//用偏積表,m2當成下標,出可變副本part.resize(part.len() + shift, 0); // 更高效的偏移,低位補 0result = ternary_stack_adder(result, part);//加入當前部分積}result
}fn main() {let stack1=vec![1,1,0,1];let stack2=vec![1,0,1,1];let re=ternary_mul_base(stack1,stack2);print!("{:?}",re);
}

結果正確。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86203.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86203.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86203.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決Vue2官網Webpack源碼泄露漏洞

一&#xff1a;漏洞產生 Webpack是一個JavaScript應用程序的靜態資源打包器。大部分Vue等應用項目會使用Webpack進行打包&#xff0c;如果沒有正確配置&#xff0c;就會導致項目源碼泄露&#xff0c;可能泄露的各種信息如API、加密算法、管理員郵箱、內部功能等等。 F12查看源…

新中國風通用讀書頌詞分享PPT模版

新國風PPT模版&#xff0c;古風影視劇PPT模版&#xff0c;天青色中國風讀書頌詞分享會PPT模版&#xff0c;國風通用PPT模版&#xff0c;茶味PPT模版&#xff0c;風雪夜歸人PPT模版&#xff0c;小別離PPT模版&#xff0c;西江月茶詞PPT模版 新中國風通用讀書頌詞分享PPT模版&…

Rust自動化測試的框架

Rust實現Web自動化測試的框架 以下是10個使用Rust實現Web自動化測試的框架示例,涵蓋不同場景和工具鏈: 使用thirtyfour(基于Selenium) use thirtyfour::prelude::*;async fn example_selenium() -> WebDriverResult<()> {let caps = DesiredCapabilities::chro…

MySQL性能測試模板

引言&#xff1a;為什么MySQL性能測試如此重要&#xff1f; 你是否遇到過這些問題&#xff1a; 線上數據庫突然卡頓&#xff0c;QPS暴跌&#xff1f;業務高峰期MySQL服務器CPU 100%&#xff0c;卻找不到瓶頸&#xff1f;新功能上線后&#xff0c;數據庫性能不升反降&#xff…

第八課:大白話教你邏輯回歸

這節課咱們來聊聊 邏輯回歸(Logistic Regression),別看名字里有“回歸”,它其實是用來干 分類 的活兒的!我會用最接地氣的方式,從定義講到實戰,保證你笑著學會,還能拿去忽悠朋友! 一:邏輯回歸是啥?——當回歸想不開,轉行搞分類 1.1 定義:邏輯回歸是個“概率算命…

項目中后端如何處理異常?

為了統一管理異常&#xff0c;在項目中封裝了自定義異常類(BusinessException),全局異常處理器(GlobalExceptionHandler), 以及一些狀態碼(ErrorCode), 便于前端統一處理異常. 主要流程如下: 當項目業務發生邏輯錯誤時,會拋出BusinessException, 其中包含自定義錯誤碼和信息.…

群暉 NAS Docker 鏡像加速配置詳細教程

通過為群暉NAS的Docker配置鏡像倉庫加速服務&#xff0c;可顯著提升鏡像拉取速度與穩定性。本指南詳細介紹使用毫秒鏡像 (1ms.run) 服務的配置步驟及日常使用方法。 一、配置前準備 開始配置前&#xff0c;推薦使用毫秒鏡像的免登錄方式獲取鏡像倉庫地址。相比傳統的賬號密碼…

Deepoc行業垂直大模型作為行業知識與AI深度融合的專用工具

一、??行業專用智能診斷與預測性維護?? ??設備健康管理?? ??多源異構數據融合??&#xff1a;垂直大模型通過時序對齊算法&#xff08;如動態時間規整DTW&#xff09;整合振動&#xff08;5kHz&#xff09;、溫度&#xff08;1Hz&#xff09;、電流等多維度傳感器數…

內存泄漏系列專題分析之二十五:內存泄漏測試report Camera相機進程各種內存指標dump方式

【關注我,后續持續新增專題博文,謝謝!!!】 上一篇我們講了:內存泄漏系列專題分析之二十四:內存泄漏測試Camera相機進程內存指標分布report概述 這一篇我們開始講: 內存泄漏系列專題分析之二十五:內存泄漏測試report Camera相機進程各種內存指標dump方式 目錄 一、問…

mysql 加鎖算法 詳解

鎖 鎖分類 從鎖的操作劃分 共享鎖和排他鎖 共享鎖&#xff08;讀鎖&#xff09;和排他鎖&#xff08;寫鎖&#xff09;。對于更新語句&#xff0c;InnoDB會自動加上排他鎖&#xff1b;對于查詢語句&#xff0c;如果是快照讀&#xff0c;由于MVCC的存在&#xff0c;InnoDB不會…

使用EasyExcel導出帶下拉框選項excel模板

使用EasyExcel導出excel模版&#xff0c;表頭字段動態生成下拉框選擇&#xff0c;并且阻止輸入不符合下拉框選項的值&#xff0c;會在表格進行提示。 為了避免excel下拉框選項過多&#xff0c;導致下拉框內容不顯示&#xff0c;新建一個sheet頁&#xff0c;將下拉框內容存儲在…

自動化 UI 測試智能體在 Trae 平臺的部署體驗

我用Trae 做了一個有意思的Agent 「自動化 UI 測試」。 點擊 Trae - AI 原生 IDE 立即復刻&#xff0c;一起來玩吧&#xff01; 前言 用戶界面&#xff08;UI&#xff09;作為用戶與軟件交互的窗口&#xff0c;其質量直接影響用戶體驗和產品口碑。傳統的手動 UI 測試不僅效率…

身份證識別接口功能與應用場景-Android證件識別api集成

數字化信息高速發展的時代&#xff0c;信息的高效處理與精準識別已成為眾多行業發展的關鍵驅動力。針對聯網平臺身份核驗過程中&#xff0c;證件信息手動錄入效率低、出錯率高、用戶體驗差等問題推出了身份證識別接口&#xff0c;旨在為各行各業提供高效與便捷的身份核驗解決方…

POJ2718-Smallest Difference(窮竭搜索:全排列)

題目描述 給定一些不同的十進制數字&#xff0c;您可以通過選擇這些數字的一個非空子集并以某種順序編寫它們來形成一個整數。剩余的數字可以以某種順序寫下來形成第二個整數。除非結果整數為 0&#xff0c;否則整數可能不以數字 0 開頭。 例如&#xff0c;如果給定數字 0, 1…

銀行賬戶管理系統-交互系統

這篇博文是對上一篇(銀行賬戶管理系統)的提升,上一篇是基礎的學習,這一篇是在上一篇的基礎上做的交互系統。Tkinter基礎函數知識點點擊下面超鏈接就可以跳轉到對應的界面。希望可以幫助到你。這是則篇的框架銀行賬戶管理系統代碼解釋-CSDN博客介紹。 寫文章-CSDN創作中心h…

基于大數據的社會治理與決策支持方案PPT(66頁)

大數據引領社會治理新變革 大數據技術的興起&#xff0c;為社會治理帶來了前所未有的變革。它改變了我們認識社會的方式&#xff0c;使得社會治理更加精準、高效。通過大數據融合分析&#xff0c;實現了對社會動態的全面監控和深度挖掘。 構建城市塊數據中心 以“社會治理”…

Containerd容器技術

目錄 一&#xff0c;containerd概述 1&#xff0c;containerd 概述 2&#xff0c;containerd 的主要功能 1. 容器生命周期管理 2. 與底層基礎設施交互 3. 與上層系統集成 3&#xff0c;containerd 的核心特點 1. 輕量級與低資源消耗 2. 標準化與開放性 3. 高性能與穩定…

awk命令詳解

Shell AWK 命令詳解 一、AWK 簡介與基本語法 AWK 是一種強大的文本處理工具,名稱來源于其三位創始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 的姓氏首字母。它逐行掃描文件,尋找匹配特定模式的行并執行相應操作。 基本語法結構: awk [選項] 模式 {動作} 文件名…

面試150跳躍游戲

思路 貪心算法&#xff0c;使用變量cover表示當前所能覆蓋的最大距離&#xff0c;如果cover大于等于n-1表示能覆蓋到&#xff0c;反之則不能 class Solution:def canJump(self, nums: List[int]) -> bool:if not nums:return Falsenlen(nums)cover0for i in range(n):if i…

磁懸浮軸承溫度漂移克星:三招實現精準控制

在磁懸浮軸承&#xff08;Active Magnetic Bearing, AMB&#xff09;的高性能應用中&#xff0c;位置傳感器的精度就是系統的生命線。然而&#xff0c;傳感器輸出隨溫度變化產生的漂移&#xff08;溫漂&#xff09;&#xff0c;如同一個潛伏的破壞者&#xff0c;悄然引入測量誤…