大数运算实现(C++)

来源:互联网 发布:淘宝搜不到相关 编辑:程序博客网 时间:2024/05/06 21:37

实现带符号的大数运算的+,-,*,/,mod以及最大公约数和模数的乘法逆元,参考了以前(不知道哪搜集到的)大数运算的代码实现并进行封装。

本人对C++理解不深,如有错误,欢迎指正!

ClassBigInteger.h

/**************************************************************************Copyright:Xidian UniversityAuthor: bluefire1991Date:2013-11-5Description:Provide a Class for Computing BigInteger**************************************************************************/#ifndef CLASSBIGINT#define CLASSBIGINT#include <string>class BigInteger{public:BigInteger();BigInteger(const BigInteger &);BigInteger(std::string num1);~BigInteger();private:std::string _num1;public://静态方法static int compare(std::string num1,std::string num2);//if num1>num2,return 1,else if num1=num2,return 0,else return -1;static std::string add(std::string num1,std::string num2);//num1+num2static std::string minus(std::string num1,std::string num2);//num1-num2static std::string multiply(std::string num1,std::string num2);//num1*num2static std::string divide(std::string num1,std::string num2,int floatpoint);//num1/num2static std::string mod(std::string num1,std::string num2);//num1 mod num2static std::string gcd(std::string num1,std::string num2);//gcd(num1,num2)static std::string exgcd(std::string a,std::string b,std::string &x,std::string &y);//if gcd(a,b)=1,a*x+b*y=1,return gcd(a,b),x is inverse of a//重载操作符std::string getnumber() const;BigInteger& operator+(const BigInteger&);//+BigInteger& operator-(const BigInteger&);//-BigInteger& operator*(const BigInteger&);//*BigInteger& operator/(const BigInteger&);///BigInteger& operator%(const BigInteger&);//mod};#endif CLASSBIGINT


ClassBigInteger.cpp

#include "ClassBigInteger.h"BigInteger::BigInteger(){}BigInteger::BigInteger(std::string num1):_num1(num1){}BigInteger::BigInteger(const BigInteger &bi){_num1=bi._num1;}BigInteger::~BigInteger(){}std::string BigInteger::getnumber() const{return _num1;}BigInteger& BigInteger::operator+(const BigInteger &bi){_num1=add(_num1,bi._num1);return *this;}BigInteger& BigInteger::operator-(const BigInteger &bi){_num1=minus(_num1,bi._num1);return *this;}BigInteger& BigInteger::operator*(const BigInteger &bi){_num1=multiply(_num1,bi._num1);return *this;}BigInteger& BigInteger::operator/(const BigInteger &bi){_num1=divide(_num1,bi._num1,0);return *this;}BigInteger& BigInteger::operator%(const BigInteger &bi){_num1=mod(_num1,bi._num1);return *this;}int BigInteger::compare(std::string number1,std::string number2){if(number1[0]!='-'&&number2[0]!='-'){int j;int length1 = number1.size();int length2 = number2.size();if(number1.size() == 0) number1 = "0";if(number2.size() == 0) number2 = "0";j = 0;for(int i = 0; i < length1; ++i){if(number1[i] == '0') ++j;else break;}number1 = number1.substr(j);j = 0;for(int i = 0; i < length2; ++i){if(number2[i] == '0') ++j;else break;}number2 = number2.substr(j);length1 = number1.size();length2 = number2.size();if(length1 > length2){return 1;}else if(length1 == length2){if(number1.compare(number2) > 0){return 1;}else if(number1.compare(number2) == 0){return 0;}else{return -1;}}else {return -1;}}else if(number1[0]=='-'&&number2[0]!='-'){return -1;}else if(number1[0]!='-'&&number2[0]=='-'){return 1;}else{std::string absnumber1="";std::string absnumber2="";for(size_t i=1;i<number1.size();i++){absnumber1+=number1[i];}for(size_t i=1;i<number2.size();i++){absnumber2+=number2[i];}int result=compare(absnumber1,absnumber2);if(result==1){return -1;}else if(result==-1){return 1;}else{return 0;}}}std::string BigInteger::add(std::string number1,std::string number2){if(number1[0]!='-'&&number2[0]!='-'){int i;int length1 = number1.size();int length2 = number2.size();std::string result="";reverse(number1.begin(), number1.end());reverse(number2.begin(), number2.end());for(i = 0; i < length1 && i < length2; i++){char c = (char)(number1[i] + number2[i] - 48);//每一位相加,-48减去ascii的'0'result = result + c;//把结果给result}//加上剩余比较长的数while(i < length1){result = result + number1[i]; ++i;}while(i < length2){result = result + number2[i]; ++i;}//转化int carry = 0;for(i = 0; i < (int)result.size(); ++i){int value = result[i] - 48 + carry;result[i] = (char)(value % 10 + 48);carry = value / 10;}if(carry !=0 ) {result = result + (char)(carry + 48);}for(i = result.size() - 1; i >= 0; i--){if(result[i] != '0')break;}//截取有效位,有的数前面是用0来填充的result = result.substr(0, i + 1);//翻转回来reverse(result.begin(), result.end());if(result.length() == 0) result = "0";return result;}else if(number1[0]=='-'&&number2[0]!='-'){std::string absnumber1="";for(size_t i=1;i<number1.size();i++){absnumber1+=number1[i];}std::string result=minus(number2,absnumber1);return result;}else if(number1[0]!='-'&&number2[0]=='-'){std::string absnumber2="";for(size_t i=1;i<number2.size();i++){absnumber2+=number2[i];}std::string result=minus(number1,absnumber2);return result;}else{std::string absnumber1="";std::string absnumber2="";for(size_t i=1;i<number1.size();i++){absnumber1+=number1[i];}for(size_t i=1;i<number2.size();i++){absnumber2+=number2[i];}return "-"+add(absnumber1,absnumber2);}}std::string BigInteger::minus(std::string number1,std::string number2){if(number1[0]!='-'&&number2[0]!='-'){int i;std::string result = "";int length1 = number1.size();int length2 = number2.size();if(compare(number2,number1) > 0){return "-" + minus(number2, number1);}reverse(number1.begin(),number1.end());reverse(number2.begin(),number2.end());for(i = 0; i < length1 && i < length2; i++){char c = number1[i] - number2[i] + 48;result = result + c;}if(i < length1){for(; i < length1; i++){result = result + number1[i];}}int carry = 0;for(i = 0; i < (int)result.length(); i++){int value = result[i] - 48 + carry;if(value < 0){value = value + 10;carry = -1;}elsecarry = 0;result[i]=(char)(value + 48);}for(i = result.size() - 1; i >= 0; i--){if(result[i] != '0')break;}result = result.substr(0, i+1);reverse(result.begin(), result.end());if(result.length()==0) result = "0";return result;}else if(number1[0]=='-'&&number2[0]!='-'){std::string absnumber1="";for(size_t i=1;i<number1.size();i++){absnumber1+=number1[i];}std::string result=add(number2,absnumber1);return "-"+result;}else if(number1[0]!='-'&&number2[0]=='-'){std::string absnumber2="";for(size_t i=1;i<number2.size();i++){absnumber2+=number2[i];}std::string result=add(number1,absnumber2);return result;}else{std::string absnumber1="";std::string absnumber2="";for(size_t i=1;i<number1.size();i++){absnumber1+=number1[i];}for(size_t i=1;i<number2.size();i++){absnumber2+=number2[i];}return minus(absnumber2,absnumber1);}}std::string BigInteger::multiply(std::string number1,std::string number2){if(number1[0]!='-'&&number2[0]!='-'){int i, j;int *iresult;int length1 = number1.size();int length2 = number2.size();std::string result = "";reverse(number1.begin(), number1.end());reverse(number2.begin(), number2.end());iresult = (int*)malloc(sizeof(int) * (length1 + length2 + 1));memset(iresult, 0, sizeof(int) * (length1 + length2 + 1));for(i = 0; i < length1; i++){for(j = 0; j < length2; j++){iresult[i+j] += ((number1[i] - 48) * (number2[j] - 48));}}int carry = 0;for(i = 0; i < length1 + length2; i++){int value = iresult[i] + carry;iresult[i] = value % 10;carry = value / 10;}for(i = length1 + length2 - 1; i >= 0; i--){if(iresult[i] != 0)break;}for(; i >= 0; i--){result = result + (char)(iresult[i]+48);}free(iresult);if(result == "") result = "0";return result;}else if(number1[0]=='-'&&number2[0]!='-'){std::string absnumber1="";for(size_t i=1;i<number1.size();i++){absnumber1+=number1[i];}std::string result=multiply(number2,absnumber1);return "-"+result;}else if(number1[0]!='-'&&number2[0]=='-'){std::string absnumber2="";for(size_t i=1;i<number2.size();i++){absnumber2+=number2[i];}std::string result=multiply(number1,absnumber2);return "-"+result;}else{std::string absnumber1="";std::string absnumber2="";for(size_t i=1;i<number1.size();i++){absnumber1+=number1[i];}for(size_t i=1;i<number2.size();i++){absnumber2+=number2[i];}return multiply(absnumber2,absnumber1);}}std::string BigInteger::divide(std::string number1,std::string number2,int floatpoint = 0){if(number1[0]!='-'&&number2[0]!='-'){int i, j, pos;std::string result = "";std::string tempstr = "";int length1 = number1.size();int length2 = number2.size();if((compare(number2, number1) > 0) && (floatpoint == 0)){return "0";}tempstr = number1.substr(0, length2);pos = length2 - 1;while(pos < length1){int quotient = 0;while(compare(tempstr, number2) >= 0){quotient++;tempstr = minus(tempstr, number2);}result = result + (char)(quotient + 48);pos++;if(pos < length1){tempstr += number1[pos];}}if(floatpoint > 0){result += '.';std::string stmp = "1";int itmp = 0;for(int k = 0; k < floatpoint; ++k){stmp += '0';if(compare(multiply(minus(number1, multiply(divide(number1, number2), number2)), stmp), number2) < 0){result += '0';++itmp;}}std::string temp = divide(multiply(minus(number1, multiply(divide(number1, number2), number2)), stmp), number2);if(temp[0] != '0') result += temp;}j = result.size();for(i = 0; i < j; i++) {if(result[i] != '0') break;}result = result.substr(i, j);return result;}else if(number1[0]=='-'&&number2[0]!='-'){std::string absnumber1="";for(size_t i=1;i<number1.size();i++){absnumber1+=number1[i];}std::string result=divide(absnumber1,number2);return "-"+result;}else if(number1[0]!='-'&&number2[0]=='-'){std::string absnumber2="";for(size_t i=1;i<number2.size();i++){absnumber2+=number2[i];}std::string result=divide(number1,absnumber2);return "-"+result;}else{std::string absnumber1="";std::string absnumber2="";for(size_t i=1;i<number1.size();i++){absnumber1+=number1[i];}for(size_t i=1;i<number2.size();i++){absnumber2+=number2[i];}return divide(absnumber1,absnumber2);}}std::string BigInteger::mod(std::string number1,std::string number2){if(compare(number1, number2) == 0){return "0";}else if(number2[0]=='-'){return "error";}else{std::string result=minus(number1, multiply(divide(number1, number2), number2));if(compare("0",result)>0){result=add(result,number2);}return result;}}std::string BigInteger::gcd(std::string num1,std::string num2){if (num1 == "0"){return num2;}if (num2 == "0"){return num1;}if (compare(num1,num2)==0){std::string temp=num1;num1=num2;num2=temp;}std::string result = mod(num1,num2);while(result != "0"){num1 = num2;num2 = result;result = mod(num1,num2);}return num2;}std::string BigInteger::exgcd(std::string a,std::string b,std::string &x,std::string &y){if( b == "0" ) {  x = "1";  y = "0";  return a;}  else{  std::string x1,y1;if(mod(a,b)=="error"){return "error";}std::string d = exgcd ( b ,mod(a,b),x1,y1);x = y1;std::string temp=divide(a,b);std::string temp2=multiply(temp,y1);y=minus(x1,temp2);return d;}}
测试代码test.cpp(将上面的.h文件加到头文件目录下,.cpp加到源文件目录下)

#include<iostream>#include "ClassBigInteger.h"using namespace std;int main(int argc, char* argv[]){//测试方法/*string num1="-1757316971";string num2="-1232142354";BigInteger *b=new BigInteger();string resultadd=b->add(num1,num2);cout<<"add result:"<<resultadd<<endl;delete(b);*/BigInteger b1("3413255");BigInteger b2("12345");BigInteger b3("234");BigInteger b4("3467");BigInteger b5("345");b1=((b1+b2)*b3/b4)%b5;cout<<"result:"<<b1.getnumber()<<endl;system("pause");return 0;}

输出结果如下: