大数的c++实现,包括加减乘法
2012-11-23 14:03
323 查看
采用vector<int>实现的大整型数类,重载了 +,-,*,+=,-=,*= 操作符;通过了
poj 2389 大数乘法的测试数据;别的不多说,上代码,供大家学习交流。
poj 2389 大数乘法的测试数据;别的不多说,上代码,供大家学习交流。
#ifndef BIG_INT_HEAD #define BIG_INT_HEAD #include<iostream> #include<vector> using namespace std; class BigInt{ private: vector<unsigned int> num; bool isPositive; // positive number or negative number int length; // the length of the vector being used int compare(const BigInt & n); // compare if abs(this) is bigger than abs(n) void plus(const BigInt & n); // add 2 BigInt with the same sign void minus(const BigInt & n); // minus 2 BigInt with the same sign void multi(const BigInt & n); void shrink(){ for(int i=length-1;i>0&&num[i]==0;i--) //shrink length length--; //length will be at least 1 } public: static const int CARRY = 10000; // if(num[i]>CARRY) num[i]/CARRY should be carried to num[i+1] static const int DIGIT = 4; // correspond to CARRY BigInt& operator+=(const BigInt & n){ bool help = (isPositive&&!n.isPositive) || (!isPositive&&n.isPositive); // opposite sign if(help){ isPositive = !isPositive; *this -= n; isPositive = !isPositive; } else plus(n); return *this; } BigInt& operator-=(const BigInt & n){ bool help = (isPositive&&!n.isPositive) || (!isPositive&&n.isPositive); // opposite sign if(help){ isPositive = !isPositive; *this += n; isPositive = !isPositive; } else minus(n); return *this; } BigInt& operator*=(const BigInt & n){ multi(n); return *this; } BigInt& operator+(const BigInt & n){ BigInt * nn = new BigInt(*this); *nn += n; return *nn; } BigInt& operator-(const BigInt & n){ BigInt * nn = new BigInt(*this); *nn -= n; return *nn; } BigInt& operator*(const BigInt & n){ BigInt * nn = new BigInt(*this); *nn *= n; return *nn; } BigInt(const char s[]); BigInt():length(1),isPositive(1){num.push_back(0);} void printNum(){ if(length<=0){ throw -1; } if(!isPositive) cout<<'-'; printf("%d",num[length-1]); for(int i=length-2;i>=0;i--) printf("%0*d",DIGIT,num[i]); cout<<endl; } }; BigInt::BigInt(const char s[]){ // construct BigInt by a string like "123" or "-2345" length = 0; int i = 0; if(s[i]=='-'){ isPositive = 0; i++; } else if(s[i]=='+'){ isPositive = 1; i++; } int len = strlen(s); int val; for(int k=len;k>i;k-=DIGIT){ val = 0; int j = k-DIGIT; if(j<i) j = i; for(;j<k;j++){ if(s[j]>'9'||s[j]<'0'){ //length = 0; throw -1; } val *= 10; val += s[j]-'0'; } num.push_back(val); length ++; } } void BigInt::plus(const BigInt & n){ //add BigInt n to this int carry = 0; int i,t; if(&n==this){ // this += this; copy a new one to help BigInt nn = BigInt(n); plus(nn); return ; } for(;length<n.length;length++) num.push_back(0); for(i=0;i<n.length;i++){ t = num[i] + n.num[i] + carry; num[i] = t % CARRY; carry = t / CARRY; } if(carry>0){ for(;i<length&&carry;i++){ t = num[i] + carry; num[i] = t % CARRY; carry = t / CARRY; } if(carry>0){ length++; //expand length num.push_back(carry); } } } void BigInt::minus(const BigInt &n){ BigInt const * nn1 = this; BigInt const * nn2 = &n; int cmp = compare(n); if(&n==this || cmp==0){ // result is 0 num.clear(); num.push_back(0); length = 1; return; } if(cmp<0){ isPositive = !isPositive; nn1 = &n; nn2 = this; } const BigInt & n1 = *nn1; const BigInt & n2 = *nn2; for(;length<n.length;length++) num.push_back(0); int carry = 0; //borrow int i,t; for(i=0;i<n2.length;i++){ // n2.length<=n2.length t = n1.num[i] - n2.num[i] - carry; if(t<0){ t += CARRY; carry = 1; } num[i] = t; } if(carry>0){ for(;i<n1.length&&carry;i++){ t = n1.num[i] - carry; if(t<0){ t += CARRY; carry = 1; } num[i] = t; } } shrink(); } void BigInt::multi(const BigInt &n){ if((isPositive&&!n.isPositive)||(!isPositive)&&n.isPositive) isPositive = 0; else isPositive = 1; if(&n==this){ BigInt n2(n); multi(n2); return; } int t,c; BigInt nn(*this); *this -= *this; // set to zero for(int i=0;i<n.length;i++){ for(int j=0;j<nn.length;j++){ t = n.num[i]*nn.num[j]; c = t/CARRY; BigInt tn; tn.length += (i+j); tn.num.clear(); for(int k=0;k<i+j;k++) tn.num.push_back(0); tn.num.push_back(t%CARRY); if(c){ tn.length++; tn.num.push_back(c); } *this+=tn; } } } /** compare the abs value of the two BigInt **/ int BigInt::compare(const BigInt & n){ if(length>n.length) return 1; if(length<n.length) return -1; for(int i=length-1;i>=0;i--){ if(num[i]>n.num[i]) return 1; if(num[i]<n.num[i]) return -1; } return 0; } #endif
相关文章推荐
- C++实现高精度乘法
- Python实现多项式加减乘法
- 通过链表实现的多项式乘法【C++】
- LeetCode Multiply Strings 高精度乘法C++实现
- 用C++实现时间的加减运算
- 39、C++定义一个类,实现向量的加减运算
- 复数乘法运算(三次实数乘法)-c++代码实现及运行实例结果
- LeetCode Multiply Strings 高精度乘法C++实现
- 矩阵链乘法问题(给A1A2A3...An加括号,使之乘法次数最小)动态规划问题C++实现
- 矩阵链乘法问题(给A1A2A3...An加括号,使之乘法次数最小)动态规划问题C++实现
- 【C++】实现双向链表的所有操作,包括逆置双链表(三种方法)
- C++实现单例模式(包括采用C++11中的智能指针)
- 复数乘法运算(三次实数乘法)-c++代码实现及运行实例结果
- 大数乘法的分治策略C++实现
- 【数据结构】用C++实现双链表的各种操作(包括头删,尾删,插入,逆序,摧毁,清空等等)
- 大数乘法C++实现
- C++实现矩阵链乘法利用动态规划及运行实例结果
- 【数据结构】用C++实现单链表的各种操作(包括头删,尾删,插入,逆序,摧毁,清空等等)
- 【数据结构】用C++实现双循环链表的各种操作(包括头删,尾删,插入,逆序,摧毁,清空等等)
- C++实现矩阵链乘法利用动态规划及运行实例结果