C++实现大数运算(加减乘除求余)
生活随笔
收集整理的這篇文章主要介紹了
C++实现大数运算(加减乘除求余)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前言:
只有部分GCC編譯器支持int128,而我們平常使用的軟件,最大只有_int64.當(dāng)這些不夠用時,我們該怎么辦?
我本身想寫代碼實現(xiàn)整數(shù)型大數(shù)據(jù)的加減乘除和求余,結(jié)果寫著寫著想著連小數(shù)運算的也一起寫上(反正加的代碼不多)
電腦是死的,人是活的,當(dāng)數(shù)據(jù)超出范圍時,我們可以想其他方法去算,在這里,我使用string類來存數(shù)據(jù),string類的容量足夠大,相信夠一般大數(shù)據(jù)使用了吧。
編譯軟件:vs2013
程序功能: 大型整數(shù)、小數(shù)的加、減、乘、除、求余
代碼:
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); //兩數(shù)的運算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時,返回余數(shù)string DIV_INT(string str1, string str2); //高精度除法,返回商string MOD_INT(string str1, string str2); //高精度除法,返回余數(shù)large(large &e); //拷貝構(gòu)造~large(){}; //析構(gòu)函數(shù) };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)//兩數(shù)的運算 {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] == '-') //負(fù)負(fù){sign = -1;str = ADD_INT(str1.erase(0, 1), str2.erase(0, 1));//erase(first,last);刪除從first到last之間的字符}else //負(fù)正{str = SUB_INT(str2, str1.erase(0, 1));}}else{if (str2[0] == '-') //正負(fù){str = SUB_INT(str1, str2.erase(0, 1));}else //正正,把兩個整數(shù)對齊,短整數(shù)前面加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記錄進(jìn)位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;}//去出結(jié)果中多余的前導(dǎo)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"; //記錄當(dāng)前值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);}//去除結(jié)果中的前導(dǎo)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時,返回余數(shù) {string quotient, residue; //定義商和余數(shù)int sign1 = 1, sign2 = 1;if (str2 == "0") //判斷除數(shù)是否為0{quotient = "ERROR!";residue = "ERROR!";if (flag == 1)return quotient;else return residue;}if (str1 == "0") //判斷被除數(shù)是否為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(),當(dāng)隊列空時,返回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;}//去除結(jié)果中的前導(dǎo)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) //高精度除法,返回余數(shù) {return DIVIDE_INT(str1, str2, 0); }運行結(jié)果展示:
例子:多位數(shù)的小數(shù)相加:
這下子就不怕數(shù)據(jù)超出范圍了,歡迎一起探討,一起交流。
?
總結(jié)
以上是生活随笔為你收集整理的C++实现大数运算(加减乘除求余)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PopupWindow需要设置边距
- 下一篇: h5 移动开发 html页面跳转,ios