日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

大数高精度加减、乘除、开根(C++版全套最详细、最易懂)

發布時間:2024/1/8 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大数高精度加减、乘除、开根(C++版全套最详细、最易懂) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大數高精度加減、乘除、開根

  • 一、前面鋪墊
  • 二、加法
  • 三、減法
  • 四、乘法
  • 五、除法
  • 六、開根(待完善)

??大數高精度加減乘除主要用在超過long型的數字計算(比如1000位數), 最基本的思路就是換成string類型變量 / char數組進行計算,小白在這里胡說八道,有不足的歡迎大大、juju們斧正v( ?? ω ?? )?

一、前面鋪墊

??這里主要用到兩個函數,moveFrontZero()用來去除前面的0且一般用在最后將要輸出結果的時候,align()用來給短的數字補0至兩個數有相同位數(相同長度)。

/** 去除前面的0 */ void moveFrontZero(string &res){res.erase(0, res.find_first_not_of('0'));if(res.empty()) res = "0"; }/** 補位對齊并返回最長的長度 */ int align(string &a, string &b){while(a.length() < b.length()) a = "0" + a;while(b.length() < a.length()) b = "0" + b;return a.length(); }

?

二、加法

??從最低位(個位)開始對應相加,超過10就進位+1,通過拼接字符串形成計算結果。
??可對應洛谷題:👉洛谷題👈

string add(string &a, string &b){string res;int len = align(a, b);for(int i = len-1; i >= 0; i--){int num1 = a[i] - '0';int num2 = b[i] - '0';if(num1 + num2 > 9 && i != 0){a[i-1] = a[i-1] - '0' + 1 + '0';res = to_string(num1 + num2 - 10) + res; //字符串拼接}else res = to_string(num1+num2) + res;}moveFrontZero(res);return res; }

?

三、減法

??從低位開始對應相減,不夠減就從借位減一。這里實現的還不是很優(有待優化),因為有個前提——兩個數都必須是整數且不是負數。

string sub(string &a, string &b){ //subductionstring res;int len = align(a, b);bool flag = false; //用來判斷最后結果是否為負數if(a<b){flag = true;a.swap(b); //確保a是最大數}for(int i = len-1; i >= 0; i--){int num1 = a[i] - '0';int num2 = b[i] - '0';if(num1 < num2){// -'0'-1是為了借位,+'0'是為了還原成char類型字符a[i-1] = a[i-1]-'0' - 1 + '0';res = to_string(num1+10 - num2) + res;}else{res = to_string(num1 - num2) + res;}}moveFrontZero(res);if(flag) res = "-" + res;return res; }

?

四、乘法

?主要思想是把乘法轉換成加法運算,分割相對小的數,如:
12345×24 可分割24成4個12345相加,20個123456相加(也就是2個123450相加),即 12345×24 = 4×12345 + 2×123450

/*** 版本一:通過string處理*/ string mul(string &a, string &b){string res = "0";align(a, b);if(a < b) a.swap(b); //固定:a永遠是最大的,b永遠是最小的for(int i = b.size()-1; i >= 0; i--){int num1 = b[i] - '0';if(i != b.size()-1) a = a + "0";for(int j = 0; j < num1; j++)res = add(res, a);}moveFrontZero(res);return res; }/*** 版本二:通過vector處理*/ vector<int> mul(vector<int> a, int b){vector<int> c;int t = 0; //進位for(int i = 0; i < a.size(); i++){t += a[i] * b;c.push_back(t % 10);t /= 10;}while(y){c.push_back(t % 10);t /= 10;}return c; }int main(){...vector<int> res;res.push_back(1);...for(int i = res.size()-1; i >= 0; i--)printf("%d", res[i]);puts("");return 0; }

??看下圖數據更易懂~
首先初始化

循環加上4次加上12345后結果res=49380

重復,循環2次加上123450,res=296280

?

五、除法

??這里用的是算商數、余數的除法,而直接除的算法有待研究和優化。
鏈接:👉大數除法👈
下面附上鏈接里算法的修正版式

string div(string &a, string &b){string res;stringstream sstream; //定義個字符串流//被除數 除數 余數int dividend, divisor = stoi(b), remainder = 0, i; for(i = 0; i < a.length()-1; i++){dividend = (a[i] - '0') + remainder*10;if(dividend >= divisor){sstream << dividend / divisor;remainder = dividend % divisor;}else{//數字的首位小于除數時,不打印0if(i != 0) sstream << "0"; remainder = dividend;}}dividend = (a[i] - '0') + remainder*10; //處理最后一位數string temp;sstream >> temp;res = temp + to_string(dividend / divisor) + "......" + to_string(dividend % divisor);moveFrontZero(res);return res; }

六、開根(待完善)

??題目鏈接:題目跳轉

總結

以上是生活随笔為你收集整理的大数高精度加减、乘除、开根(C++版全套最详细、最易懂)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。