int128的實現(基本完成)

雖然有一個聲明叫_int128但是這并不是C++標準:

long long 不夠用?詳解 __int128 - FReQuenter - 博客園 (cnblogs.com)

網絡上去找int128的另類實現方法,發現幾乎都是在介紹_int128的

然后我就自己想了個辦法,當時還沒學C++,用C草草寫了下了事,也沒有驗證行不行

在這周一(2024/2/19)看了C++的類以及運算符重載之后,我打算拿int128來練練手

重載倒是很快練好了,但是代碼有大問題:

int128的實現(未完成)-CSDN博客

int128的實現_實現一個int128的數-CSDN博客

可以看看我之前的愚蠢的代碼

主要是完全沒注意到數爆出2^64的問題(主要體現在上面的第一篇博客,第二篇博客因為沒專門寫輸入輸出,所以沒爆掉)

還有一個非常吃屎的東西:0xFFFFFFFF這個數,是2^32-1,不是2^32

順便把輸入吞掉一個字符的問題解決了(用了ungetc函數)

說說原理吧:

總所周知,我們這里的最高位的int的位數是64位(long long),最高表示的數是2^64-1(無符號),只有18,446,744,073,709,551,615大概10的20次方,有的時候是不夠用的,用高精度數組的速度的效率又相對較慢,這時候就想到了int128了

但是只能你自己來實現(或者用上面的_int128啦,但是有的時候用不了),所以我就想了一種實現方法

用4個unsignedlonglongint值來記錄4個數,分別代表x1 * 2^96, x2 * 2 ^ 64, x3 * 2^32, x4。這樣加起來,就是一個int128的數了,而且不會爆掉(之前是用兩個數記錄高低位的,輸入輸出爆了,運算倒是沒有)

然后按照數學的計算,就可以設計出加減乘除了

代碼如下:

#ifndef CSTDIO_
#define CSTDIO_
#include<cstdio>
#endif#ifndef CCTYPE_
#define CCTYPE_
#include<cctype>
#endif#ifndef VECTOR_
#define VECTOR_
#include<vector>
#endif#ifndef INT128_H_
#define INT128_H_typedef unsigned long long LLU;//64位
typedef unsigned int U;//32位
const U MAX32 = 0xFFFFFFFF;
const LLU MAX64_U = 0xFFFFFFFF00000000;
const LLU _2POW32 = (LLU)MAX32 + 1;class INT128{LLU A, B, C, D;
public:INT128(LLU tmp = 0){A = B = 0, C = (tmp & MAX64_U) >> 32, D = tmp & MAX32;};void getnum(void);INT128 operator-(const U & tmp) const;INT128 operator+(const LLU & tmp) const;INT128 operator+(const INT128 & tmp) const;INT128 operator*(const U & tmp) const;INT128 operator/(const U & tmp) const;INT128 operator%(const U & tmp) const;void operator=(const LLU & tmp);void show(void);inline void function1(std::vector<int> & tmp, LLU & data);inline void function2(std::vector<int> & tmp, LLU & data);inline INT128 function3(INT128 & result, LLU & A1, LLU & A2, LLU & A3, LLU & A4);
};void INT128::getnum(void)
{A = B = C = D = 0;std::vector<int> tmp;char c;while(!isdigit(c = getchar()));//清空數字前面的東西do{tmp.insert(tmp.begin(), c - '0');}while(isdigit(c = getchar()));ungetc(c, stdin);//開始賦值function1(tmp, D), function1(tmp, C), function1(tmp, B);for(int i = tmp.size() - 1; i >= 0; i--)A = A * 10 + tmp[i];
}
INT128 INT128::operator-(const U & tmp) const
{LLU A1, A2, A3, A4;INT128 result(0);A1 = A, A2 = B, A3 = 0, A4 = (C << 32) + D - tmp;return function3(result, A1, A2, A3, A4);
}
INT128 INT128::operator+(const LLU & tmp) const
{LLU A1, A2, A3, A4;INT128 result(0);A1 = A, A2 = B, A3 = C, A4 = D + tmp;return function3(result, A1, A2, A3, A4);
}
INT128 INT128::operator*(const U & tmp) const
{LLU A1, A2, A3, A4;INT128 result(0);A1 = A, A2 = B, A3 = C, A4 = D;A1 *= tmp, A2 *= tmp, A3 *= tmp, A4 *= tmp;return function3(result, A1, A2, A3, A4);
}
INT128 INT128::operator/(const U & tmp) const
{LLU A1, A2, A3, A4;INT128 result(0);A1 = A, A2 = B, A3 = C, A4 = D;A2 += (A1 % tmp) << 32, A1 /= tmp;A3 += (A2 % tmp) << 32, A2 /= tmp;A4 += (A3 % tmp) << 32, A3 /= tmp;A4 /= tmp;return function3(result, A1, A2, A3, A4);
}
INT128 INT128::operator%(const U & tmp) const
{LLU A1, A2, A3, A4;INT128 result(0);A1 = A, A2 = B, A3 = C, A4 = D;A2 += (A1 % tmp) << 32;A3 += (A2 % tmp) << 32;A4 += (A2 % tmp) << 32;result.D = A4 % tmp;return result;
}
INT128 INT128::operator+(const INT128 & tmp) const
{LLU A1, A2, A3, A4;INT128 result(0);A1 = A + tmp.A, A2 = B + tmp.B, A3 = C + tmp.C, A4 = D + tmp.D;return function3(result, A1, A2, A3, A4);
}
void INT128::operator=(const LLU & tmp)
{A = B = 0, C = (tmp & MAX64_U) >> 32, D = tmp & MAX32;
}
void INT128::show(void)
{std::vector<int> tmp;//A放進數組LLU n_tmp = A;int ext = 0;while(n_tmp){tmp.push_back(n_tmp % 10);n_tmp /= 10;}//B,C,D放進數組function2(tmp, B), function2(tmp, C), function2(tmp, D);//輸出if(!tmp.size())  tmp.push_back(0);for(int i = tmp.size() - 1; i >= 0; i--)printf("%d", tmp[i]);
}
inline void INT128::function1(std::vector<int> & tmp, LLU & data)
{LLU ext = 0;bool jud = false;for(int i = tmp.size() - 1; i >= 0; i--){ext = ext * 10 + tmp[i];tmp[i] = ext / _2POW32;jud = (jud || tmp[i]) ? true : false;if(!jud)  tmp.pop_back();ext %= _2POW32;}data = ext;
}
inline void INT128::function2(std::vector<int> & tmp, LLU & data)
{LLU n_tmp = 0;int ext = 0;for(int i = 0; i < tmp.size(); i++)n_tmp += _2POW32 * (LLU)tmp[i], tmp[i] = n_tmp % 10, n_tmp /= 10;while(n_tmp){tmp.push_back(n_tmp % 10);n_tmp /= 10;}n_tmp = data, ext = 0;for(int i = 0; i < tmp.size(); i++){ext += n_tmp % 10 + tmp[i];tmp[i] = ext % 10, ext /= 10, n_tmp /= 10;}n_tmp += ext;while(n_tmp){tmp.push_back(n_tmp % 10);n_tmp /= 10;}
}
inline INT128 INT128::function3(INT128 & result, LLU & A1, LLU & A2, LLU & A3, LLU & A4)
{result.D = A4 & MAX32, A3 += (A4 & MAX64_U) >> 32;result.C = A3 & MAX32, A2 += (A3 & MAX64_U) >> 32;result.B = A2 & MAX32, A1 += (A2 & MAX64_U) >> 32;result.A = A1 & MAX32;return result;
}#endif

注:只有加法和賦值支持int128數,然后每種計算都支持常數,但是只有加法和賦值達到2^64-1,其他是2^32-1

至于為什么不讓每種計算都支持int128嘛,因為懶得寫了,還有乘法會爆int128、沒必要,而且藍橋杯要到了,我得加緊算法的學習了(這個東西花了我4天去改,雖然不是每一刻都在想,但是也挺搞事的)

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

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

相關文章

Spring Boot中實現列表數據導出為Excel文件

點擊下載《Spring Boot中實現列表數據導出為Excel文件》 1. 前言 本文將詳細介紹在Spring Boot框架中如何將列表數據導出為Excel文件。我們將通過Apache POI庫來實現這一功能&#xff0c;并解釋其背后的原理、提供完整的流程和步驟&#xff0c;以及帶有詳細注釋的代碼示例。最…

關于設備連接有人云的使用及modbus rtu協議,服務器端TCP調試設置

有人云調試 調試過程問題1. 關于modbus rtu協議,實質上有三種modbus基本原理modbus 格式2. 關于modbus crc16通信校驗3. 關于在ubuntu阿里云服務器端,監聽網絡數據之調試mNetAssist之前的一個項目,再拿出來回顧下。 調試過程 先 要在有人云,用手機號注冊一個服務賬號,官網顯…

家的情感記憶:如何用壁紙講述你的墻故事?

1、方小童在線工具集 網址&#xff1a; 方小童 該網站是一款在線工具集合的網站&#xff0c;目前包含PDF文件在線轉換、隨機生成美女圖片、精美壁紙、電子書搜索等功能&#xff0c;喜歡的可以趕緊去試試&#xff01;

HarmonyOS—使用預覽器查看應用/服務效果

DevEco Studio為開發者提供了UI界面預覽功能&#xff0c;可以查看應用/服務的UI界面效果&#xff0c;方便開發者隨時調整界面UI布局。預覽器支持布局代碼的實時預覽&#xff0c;只需要將開發的源代碼進行保存&#xff0c;就可以通過預覽器實時查看應用/服務運行效果&#xff0c…

探索分布式強一致性奧秘:Paxos共識算法的精妙之旅

提到分布式算法&#xff0c;就不得不提 Paxos 算法&#xff0c;在過去幾十年里&#xff0c;它基本上是分布式共識的代名詞&#xff0c;因為當前一批常用的共識算法都是基于它改進的。比如&#xff0c;Fast Paxos 算法、Cheap Paxos、Raft 算法等。 由萊斯利蘭伯特&#xff08;L…

Spring6學習技術|AOP

學習材料 尚硅谷Spring零基礎入門到進階&#xff0c;一套搞定spring6全套視頻教程&#xff08;源碼級講解&#xff09; AOP AOP&#xff08;Aspect Oriented Programming&#xff09;是一種設計思想&#xff0c;是軟件設計領域中的面向切面編程&#xff0c;它是面向對象編程的…

AIDL的工作原理與使用示例 跨進程通信 遠程方法調用RPC

AIDL的介紹與使用 AIDL&#xff08;Android Interface Definition Language&#xff09;是Android中用于定義客戶端和服務端之間通信接口的一種接口定義語言。它允許你定義客戶端和服務的通信協議&#xff0c;用于在不同的進程間或同一進程的不同組件間進行數據傳遞。AIDL通過…

深入探討YUV圖像處理:理論原理與OpenCV實踐

文章目錄 導言YUV模型的原理使用OpenCV處理YUV圖像1. 讀取YUV圖像2. 將YUV圖像轉換為RGB圖像3. 將RGB圖像轉換為YUV圖像 結語 導言 導言&#xff1a; 在圖像處理領域&#xff0c;YUV色彩模型因其對亮度和色度的分離而被廣泛使用&#xff0c;特別在視頻編碼和實時通信中發揮了巨…

算法項目(3)—— 從零實現KNN、樸素貝葉斯垃圾郵件分類

本文包含什么? 項目運行的方式項目代碼,自己實現KNN算法以及樸素貝葉斯算法.代碼介紹運行有問題? csdn上后臺隨時售后.項目說明 本文主要是自己從0實現KNN算法以及樸素貝葉斯算法.然后使用英文垃圾郵件數據集進行垃圾郵件分類.常見的代碼均調用sklearn庫來實現,本文自行實現…

AI推介-大語言模型LLMs論文速覽(arXiv方向):2024.01.01-2024.01.10

1.Pre-trained Large Language Models for Financial Sentiment Analysis 標題:用于金融情感分析的預訓練大型語言模型 author:Wei Luo, Dihong Gong date Time:2024-01-10 paper pdf:http://arxiv.org/pdf/2401.05215v1 摘要&#xff1a; 金融情感分析是指將金融文本內容劃分…

從零學習Linux操作系統第二十八部分 shell腳本中的執行流控制

一、什么是執行流、循環執行流 執行流&#xff1a;改變執行順序&#xff0c;使之更方便操作者 循環執行流&#xff1a;根據腳本是執行流再某一個狀態下進行循環執行&#xff0c;進行多次執行后再往下走&#xff08;for語句&#xff09; for語句 作用 為循環執行動作 for語句…

opencv判斷灰化情況

目的 先說說理論&#xff1a; 在圖像處理中&#xff0c;用RGB三個分量&#xff08;R&#xff1a;Red&#xff0c;G&#xff1a;Green&#xff0c;B&#xff1a;Blue&#xff09;&#xff0c;即紅、綠、藍三原色來表示真彩色&#xff0c;R分量&#xff0c;G分量&#xff0c;B分…

LeetCode LCR 055.二叉搜索樹迭代器

實現一個二叉搜索樹迭代器類BSTIterator &#xff0c;表示一個按中序遍歷二叉搜索樹&#xff08;BST&#xff09;的迭代器&#xff1a; BSTIterator(TreeNode root) 初始化 BSTIterator 類的一個對象。BST 的根節點 root 會作為構造函數的一部分給出。指針應初始化為一個不存在…

vue實現拖拽(vuedraggable)

實現效果: 左側往右側拖動&#xff0c;右側列表可以進行拖拽排序。 安裝引用&#xff1a; npm install vuedraggable import draggable from vuedraggable 使用&#xff1a; data數據&#xff1a; componentList: [{groupName: 考試題型,children: [{componentType: danxua…

SQLite 的使用

SQLite 是一個輕量級、自包含和無服務器的關系型數據庫管理系統&#xff08;RDBMS&#xff09;&#xff0c;廣泛應用于嵌入式系統、移動應用程序和小中型網站。它易于創建、需要的配置較少&#xff0c;并且提供了用于管理和操作數據的強大功能集。本文&#xff0c;我們將帶領你…

電路設計(26)——交通信號燈的multism仿真

1.功能要求 使用數字芯片設計一款交通信號燈&#xff0c;使得&#xff1a; 主干道的綠燈時間為60S&#xff0c;紅燈時間為45S 次干道的紅燈時間為60S&#xff0c;綠燈時間為45S 主、次干道&#xff0c;綠燈的最后5S內&#xff0c;黃燈閃爍 使用數碼管顯示各自的倒計時時間。 按…

【CMake】(5)搜索文件

方法1:使用aux_source_directory命令 aux_source_directory命令用于查找指定目錄下的所有源文件,并將文件列表存儲到一個變量中。這種方法簡單易用,適合于源文件位于單一目錄下的情況。 基本語法如下: aux_source_directory(<dir> <variable>)<dir>:…

openssl3.2 - 編譯 - zlib.dll不要使用絕對路徑

文章目錄 openssl3.2 - 編譯 - 編譯時的動態庫zlib.dll不要使用絕對路徑概述測試zlib特性在安裝好的目錄中是否正常筆記70-test_tls13certcomp.t80-test_cms.t對測試環境的猜測從頭再編譯測試安裝一次測試一下隨便改變位置的openssl用到zlib時是否好使測試一下隨便改變位置的op…

Docker Nginx 負載均衡搭建(服務宕機-配置高可用) - 附(Python案例,其它語言同理)

目錄 一 . 概要 1. 什么是負載均衡 2. 負載均衡有哪些優勢&#xff1f; &#xff08;1&#xff09;應用程序可用性 &#xff08;2&#xff09;應用程序可擴展性 &#xff08;3&#xff09;應用程序安全 &#xff08;4&#xff09;應用程序性能 3 . Nginx負載均衡調度策…

Java高級 / 架構師 場景方案 面試題(二)

1.雙十一億級用戶日活統計如何用 Redis快速計算 在雙十一這種億級用戶日活統計的場景中&#xff0c;使用Redis進行快速計算的關鍵在于利用Redis的數據結構和原子操作來高效地統計和計算數據。以下是一個基于Redis的日活統計方案&#xff1a; 選擇合適的數據結構&#xff1a; …