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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++实现大数运算(加减乘除求余)

發布時間:2024/3/13 c/c++ 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++实现大数运算(加减乘除求余) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:
只有部分GCC編譯器支持int128,而我們平常使用的軟件,最大只有_int64.當這些不夠用時,我們該怎么辦?

我本身想寫代碼實現整數型大數據的加減乘除和求余,結果寫著寫著想著連小數運算的也一起寫上(反正加的代碼不多)

電腦是死的,人是活的,當數據超出范圍時,我們可以想其他方法去算,在這里,我使用string類來存數據,string類的容量足夠大,相信夠一般大數據使用了吧。

編譯軟件:vs2013

程序功能: 大型整數、小數的加、減、乘、除、求余

代碼:

main.cpp

#include <iostream> #include<string> #include<cmath> #include "large.h" using namespace std; int main() {char ch;string m_snum1, m_snum2;while (cin>>m_snum1>>ch>>m_snum2){large _large(m_snum1, ch, m_snum2);}return 0; }

large.h

#include <iostream> #include<string> using namespace std; class large { public:large(){}large(string m_str1, char m_ch, string m_str2); //兩數的運算inline int compare(string str1, string str2); //相等返回0,大于返回1,小于返回-1string SUB_INT(string str1, string str2); //高精度減法string ADD_INT(string str1, string str2); //高精度加法string MUL_INT(string str1, string str2); //高精度乘法 string DIVIDE_INT(string str1, string str2, int flag); //高精度除法,flag==1,返回商;flag==0時,返回余數string DIV_INT(string str1, string str2); //高精度除法,返回商string MOD_INT(string str1, string str2); //高精度除法,返回余數large(large &e); //拷貝構造~large(){}; //析構函數 };

large.cpp

#include <iostream> #include<string> #include<cmath> #include "large.h" using namespace std; large::large(string m_str1, char m_ch, string m_str2)//兩數的運算 {int m_ilocation1 ;int m_ilocation2 ;string m_res;int m_istr;if (m_str1.find_first_of(".") == -1)m_ilocation1 = 0;elsem_ilocation1 = m_str1.length() - m_str1.find_first_of(".") - 1;if (m_str2.find_first_of(".") == -1)m_ilocation2 = 0;elsem_ilocation2 = m_str2.length() - m_str2.find_first_of(".") - 1;if (m_ilocation1 == 0 && m_ilocation2 == 0){switch (m_ch){case'+':m_res = ADD_INT(m_str1, m_str2); break;case'-':m_res = SUB_INT(m_str1, m_str2); break;case'*':m_res = MUL_INT(m_str1, m_str2); break;case'/':m_res = DIV_INT(m_str1, m_str2); break;case'%':m_res = MOD_INT(m_str1, m_str2); break;default:break;}}else{int m_ilocat = m_ilocation1 - m_ilocation2;int m_ilocation3;if (m_ilocation1!=0)m_str1.erase(m_str1.find_first_of("."), m_str1.find_first_not_of(".") + 1);if (m_ilocation2!=0)m_str2.erase(m_str2.find_first_of("."), m_str2.find_first_not_of(".") + 1);switch (m_ch){case'+':if (m_ilocat >= 0){for (int i = 0; i < m_ilocat; i++)m_str2 = m_str2 + '0';m_ilocation3 = m_ilocation1;}else{for (int i = 0; i < -m_ilocat; i++)m_str1 = m_str1 + '0';m_ilocation3 = m_ilocation2;}m_res = ADD_INT(m_str1, m_str2);m_istr = m_res.length();for (int i = 0; i < m_ilocation3; i++)m_istr = m_istr - 1;m_res.insert(m_istr, ".");break;case'-':if (m_ilocat >= 0){for (int i = 0; i < m_ilocat; i++)m_str2 = m_str2 + '0';m_ilocation3 = m_ilocation1;}else{for (int i = 0; i < -m_ilocat; i++)m_str1 = m_str1 + '0';m_ilocation3 = m_ilocation2;}m_res = SUB_INT(m_str1, m_str2);m_istr = m_res.length();for (int i = 0; i < m_ilocation3; i++)m_istr = m_istr - 1;m_res.insert(m_istr, ".");break;case'*':m_ilocation3=m_ilocation1+m_ilocation2;m_res = MUL_INT(m_str1, m_str2); m_istr = m_res.length();for (int i = 0; i < m_ilocation3; i++)m_istr = m_istr - 1;m_res.insert(m_istr, "."); break;case'/':if (m_ilocat >= 0){for (int i = 0; i < m_ilocat; i++)m_str2 = m_str2 + '0';}else{for (int i = 0; i < -m_ilocat; i++)m_str1 = m_str1 + '0';}m_res = DIV_INT(m_str1, m_str2); break;case'%':m_res = MOD_INT(m_str1, m_str2); break;default:break;}}cout << endl;cout << m_res << endl; } inline int large::compare(string str1, string str2) //相等返回0,大于返回1,小于返回-1 {if (str1.size() > str2.size())return 1;else if (str1.size() < str2.size())return -1;else return str1.compare(str2); //若長度相等,則從頭到尾按位比較 } string large::ADD_INT(string str1, string str2) //高精度加法 {int sign = 1;//sign為符號為string str;if (str1[0] == '-'){if (str2[0] == '-') //負負{sign = -1;str = ADD_INT(str1.erase(0, 1), str2.erase(0, 1));//erase(first,last);刪除從first到last之間的字符}else //負正{str = SUB_INT(str2, str1.erase(0, 1));}}else{if (str2[0] == '-') //正負{str = SUB_INT(str1, str2.erase(0, 1));}else //正正,把兩個整數對齊,短整數前面加0補齊{string::size_type L1, L2; //string::size_type抽象意義是尺寸單位類型int i;L1 = str1.size();L2 = str2.size();if (L1 < L2){for (i = 0; i < L2 - L1; i++)str1 = "0" + str1;}else{for (i = 0; i < L1 - L2; i++)str2 = "0" + str2;}int int1 = 0, int2 = 0; //int2記錄進位for (i = str1.size() - 1; i >= 0; i--){int1 = (int(str1[i]) - '0' + int(str2[i]) - '0' + int2) % 10;int2 = (int(str1[i]) - '0' + int(str2[i]) - '0' + int2) / 10;str = char(int1 + '0') + str;}if (int2 != 0)str = char(int2 + '0') + str;}}//運算符處理符號if ((sign == -1) && (str[0] != '0'))str = "-" + str;return str; }string large::SUB_INT(string str1, string str2) //高精度減法 {int sign = 1; //sign為符號位string str;int i, j;if (str2[0] == '-'){str = ADD_INT(str1, str2.erase(0, 1));}else{int res = compare(str1, str2);if (res == 0)return "0";if (res < 0){sign = -1;string temp = str1;str1 = str2;str2 = temp;}string::size_type tempint;tempint = str1.size() - str2.size();for (i = str2.size() - 1; i >= 0; i--){if (str1[i + tempint] < str2[i]) //借位{j = 1;while (1){if (str1[tempint - j + i] == '0'){str1[i + tempint - j] = '9';j++;}else{str1[i + tempint - j] = char(int(str1[i + tempint - j]) - 1);break;}}str = char(str1[i + tempint] - str2[i] + ':') + str;}else{str = char(str1[i + tempint] - str2[i] + '0') + str;}}for (i = tempint - 1; i >= 0; i--)str = str1[i] + str;}//去出結果中多余的前導0str.erase(0, str.find_first_not_of('0'));if (str.empty())str = "0";if ((sign == -1) && (str[0] != '0'))str = "-" + str;return str; }string large::MUL_INT(string str1, string str2) //高精度乘法 {int sign = 1;string str = "0"; //記錄當前值if (str1[0] == '-'){sign *= -1;str1 = str1.erase(0, 1);}if (str2[0] == '-'){sign *= -1;str2 = str2.erase(0, 1);}int i, j;string::size_type L1, L2;L1 = str1.size();L2 = str2.size();for (i = L2 - 1; i >= 0; i--) //模擬手工乘法豎式{string tempstr;int int1 = 0, int2 = 0, int3 = int(str2[i]) - '0';if (int3 != 0){for (j = 1; j <= (int)(L2 - 1 - i); j++)tempstr = "0" + tempstr;for (j = L1 - 1; j >= 0; j--){int1 = (int3*(int(str1[j]) - '0') + int2) % 10;int2 = (int3*(int(str1[j]) - '0') + int2) / 10;tempstr = char(int1 + '0') + tempstr;}if (int2 != 0)tempstr = char(int2 + '0') + tempstr;}str = ADD_INT(str, tempstr);}//去除結果中的前導0str.erase(0, str.find_first_not_of("0"));if (str.empty())str = "0";if ((sign == -1) && (str[0] != '0'))str = "-" + str;return str; }string large::DIVIDE_INT(string str1, string str2, int flag) //高精度除法,flag==1,返回商;flag==0時,返回余數 {string quotient, residue; //定義商和余數int sign1 = 1, sign2 = 1;if (str2 == "0") //判斷除數是否為0{quotient = "ERROR!";residue = "ERROR!";if (flag == 1)return quotient;else return residue;}if (str1 == "0") //判斷被除數是否為0{quotient = "0";residue = "0";}if (str1[0] == '-'){str1 = str1.erase(0, 1);sign1 *= -1;sign2 = -1;}if (str2[0] == '-'){str2 = str2.erase(0, 1);sign1 *= -1;}int res = compare(str1, str2);if (res < 0){quotient = "0";residue = str1;}else if (res == 0){quotient = "1";residue = "0";}else{string::size_type L1, L2;L1 = str1.size();L2 = str2.size();string tempstr;tempstr.append(str1, 0, L2 - 1); //將str1中為值0到L2-1的字符串追加到tempstrfor (int i = L2 - 1; i < L1; i++) //模擬手工除法豎式{tempstr = tempstr + str1[i];tempstr.erase(0, tempstr.find_first_not_of('0')); //在字符串中查找第一個與'0'不匹配的字符,返回它的位置if (tempstr.empty())tempstr = "0"; //q.empty(),當隊列空時,返回truefor (char ch = '9'; ch >= '0'; ch--) //試商{string str;str = str + ch;if (compare(MUL_INT(str2, str), tempstr) <= 0){quotient = quotient + ch;tempstr = SUB_INT(tempstr, MUL_INT(str2, str));break;}}}residue = tempstr;}//去除結果中的前導0quotient.erase(0, quotient.find_first_not_of("0"));if (quotient.empty())quotient = "0";if ((sign1 == -1) && (quotient[0] != '0'))quotient = "-" + quotient;if ((sign2 == -1) && (residue[0] != '0'))residue = "-" + residue;if (flag == 1)return quotient;elsereturn residue; } string large::DIV_INT(string str1, string str2) //高精度除法,返回商 {return DIVIDE_INT(str1, str2, 1); } string large::MOD_INT(string str1, string str2) //高精度除法,返回余數 {return DIVIDE_INT(str1, str2, 0); }

運行結果展示:
例子:多位數的小數相加:

這下子就不怕數據超出范圍了,歡迎一起探討,一起交流。

?

總結

以上是生活随笔為你收集整理的C++实现大数运算(加减乘除求余)的全部內容,希望文章能夠幫你解決所遇到的問題。

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