【C++】大数的+-*/四则运算

所谓大数,则指数值特别大的数,可能会有99位,100位,远远超过了long long表示的范围。

这样的数作四则运算,需要用到字符串。用字符串通过每一位的字符的四则运算来模拟。

 

废话少说,上代码:

  1 #include <iostream>
  2 #include <vector>
  3 using namespace std;
  4 
  5 class BigNum{
  6     vector<char> m_vec;
  7     //构造函数,析构函数,size()函数,友元重载>>,<<,重载[] + - * / =。
  8 public:
  9     BigNum();
 10     ~BigNum();
 11 
 12 public:
 13     int size() const {
 14         return m_vec.size();
 15     }
 16     void clr(){
 17         m_vec.clear();
 18     }
 19 
 20 public:
 21     friend ostream& operator<<(ostream &os,const BigNum &data);
 22     friend istream& operator>>(istream &is,BigNum &data);
 23 
 24 public:
 25     char operator[](int nIndex) const;
 26 
 27     BigNum operator+(const BigNum &data);
 28     BigNum operator-(BigNum &data);
 29     BigNum operator*(const BigNum &data);
 30     BigNum operator/(BigNum &data);
 31     BigNum& operator=(const BigNum &data);
 32     bool operator==(const BigNum &data);
 33     bool operator>(const BigNum &data);
 34     bool operator>=(const BigNum &data);
 35 };
 36 
 37 BigNum::BigNum(){}
 38 
 39 BigNum::~BigNum(){}
 40 
 41 ostream& operator<<(ostream &os,const BigNum &data){
 42     vector<char>::const_iterator itVec = data.m_vec.begin();
 43     for(; itVec != data.m_vec.end(); itVec++){
 44         os << *itVec;
 45     }
 46     os << endl;
 47     return os;
 48 }
 49 
 50 istream& operator>>(istream &is,BigNum &data){
 51     //必须清空is的缓冲区,不然is.get()得到的是上一次回车的\n。并且不能用is.ignore(),因为ignore()会把第一次输入的第一个字符删除掉。
 52     is.sync();
 53     while(true){
 54         char c = is.get();
 55         if(' ' == c || '\r' == c || '\n' == c)
 56             break;
 57         if( c < '0' || c > '9'){
 58             data.m_vec.clear();
 59             cerr << "not accept" << endl;
 60             break;
 61         }
 62         data.m_vec.push_back(c);
 63     }
 64     
 65     return is;
 66 }
 67 
 68 char BigNum::operator[](int nIndex) const
 69 {
 70     if(nIndex < 0 || nIndex >= m_vec.size())
 71     {
 72         cerr << "error occur in []";
 73         return ' ';
 74     }
 75     return m_vec[nIndex];
 76 }
 77 
 78 bool BigNum::operator==(const BigNum &data){
 79     if(m_vec.size() != data.m_vec.size())
 80         return false;
 81     for(int i = 0; i < m_vec.size(); i++){
 82         if(m_vec[i] != data.m_vec[i])
 83             return false;
 84     }
 85     return true;
 86 }
 87 
 88 bool BigNum::operator>(const BigNum &data){
 89     int a = m_vec.size();
 90     int b = data.m_vec.size();
 91     if(a > b){
 92         return true;
 93     }
 94     else if(a < b){
 95         return false;
 96     }
 97     else if(a == b)
 98     {
 99         for(int i = 0; i < a; i++){            
100             if(m_vec[i] > data.m_vec[i]){
101                 return true;
102             }
103             else if(m_vec[i] < data.m_vec[i]){
104                 return false;
105             }
106         }
107         return false;
108     }
109 }
110 
111 bool BigNum::operator>=(const BigNum &data){
112     if(*this > data || *this == data)
113         return true;
114     return false;
115 }
116 
117 BigNum BigNum::operator+ (const BigNum &data){
118         int nCarry = 0;
119         BigNum numTemp;
120         vector<char>& vecTemp = numTemp.m_vec; //必须是引用
121         
122         int i = data.size() - 1;
123         int j = m_vec.size() -1;
124         for(; i >= 0 || j >= 0; i--,j--){
125             char a = j>=0? m_vec[j] - '0': 0;
126             char b = i>=0? data[i] - '0' :0;
127             char c = a + b + nCarry;
128             nCarry = c / 10;
129             vecTemp.push_back(c%10 + '0');
130         }
131 
132         if(nCarry != 0)
133         {
134             vecTemp.push_back(nCarry + '0');
135         }
136 
137         //reverse vecTemp
138         for(i = 0, j = vecTemp.size() - 1; i < j; i++,j--)
139         {
140             char cTemp = vecTemp[i];
141             vecTemp[i] = vecTemp[j];
142             vecTemp[j] = cTemp;
143         }
144         return numTemp;
145 }
146 
147 BigNum& BigNum::operator=(const BigNum &data)
148 {
149     m_vec.clear();
150     vector<char>::const_iterator itVec = data.m_vec.begin();
151     for(; itVec != data.m_vec.end(); itVec++)
152     {
153         m_vec.push_back(*itVec);
154     }
155     return *this;
156 }
157 
158 BigNum BigNum::operator*(const BigNum &data){
159     int nCarry = 0;
160     BigNum result;
161     BigNum numTemp;
162     vector<char>& vecTemp = numTemp.m_vec;
163 
164     int i = data.size()-1;
165     for(; i >= 0; i--){
166         char a = data[i] - '0';
167         int j = m_vec.size() - 1;
168         for(; j >= 0; j--){
169             char b = m_vec[j] - '0';
170             char c = b * a + nCarry;
171             nCarry = c/10;
172             vecTemp.push_back(c % 10 + '0');
173         }
174         if(nCarry != 0){
175             vecTemp.push_back(nCarry + '0');
176             nCarry = 0;
177         }
178 
179         //reverse vecTemp
180         int n = 0;
181         int m = vecTemp.size() - 1;
182         for(; n < m; n++,m--){
183             char cTemp = vecTemp[n];
184             vecTemp[n] = vecTemp[m];
185             vecTemp[m] = cTemp;
186         }
187 
188         for(int t = data.size() - 1; t > i; t--)
189         {
190             vecTemp.push_back('0');
191         }
192 
193         result = result + numTemp;
194         vecTemp.clear();
195     }
196     return result;
197 }
198 
199 BigNum BigNum::operator-(BigNum &data){
200     //m_vec > data.m_vec
201     int nCarry = 0;
202     BigNum numTemp;
203     vector<char>& vecTemp = numTemp.m_vec;
204 
205     int i = data.size() - 1;
206     int j = m_vec.size() -1;
207     for(; i >= 0 || j >= 0; i--,j--){
208         char a = j>=0? m_vec[j] - '0': 0;
209         char b = i>=0? data[i] - '0' :0;
210         char c = a - nCarry;
211         if(c < b){
212             //需要借位
213             c = c + 10;
214             nCarry = 1;
215             vecTemp.push_back( (c-b) + '0');
216         }
217         else{
218             nCarry = 0;
219             vecTemp.push_back( (c-b) + '0');
220         }
221     }
222 
223     //记录前面产生几个0
224     int zero = 0;
225     vector<char>::const_iterator itVec = vecTemp.end()-1;
226     for(; ; itVec--){
227         if( *itVec == '0'){
228             zero++;
229         }
230         else
231             break;
232         if(itVec == vecTemp.begin())
233             break;        
234     }    
235 
236     //pop掉0
237     for(int k = zero; k > 0; k--)
238         vecTemp.pop_back();
239 
240     //reverse
241     for(i = 0, j = vecTemp.size() - 1; i < j; i++,j--)
242     {
243         char cTemp = vecTemp[i];
244         vecTemp[i] = vecTemp[j];
245         vecTemp[j] = cTemp;
246     }
247 
248     return numTemp;
249 }
250 
251 BigNum BigNum::operator/(BigNum &data){
252     //m_vec > data.m_vec
253     BigNum numTemp;
254     vector<char>& vecTemp = numTemp.m_vec;
255     BigNum &numThis = *this;
256 
257     int lenA = m_vec.size();
258     int lenB = data.m_vec.size();
259     for (int i = lenB; i < lenA; i++){
260         data.m_vec.push_back('0');
261     }
262     for(int j = lenB; j <= lenA; j++){
263         int a = 0;
264         while(numThis >= data){
265             numThis = numThis - data;
266             a++;
267         }
268         vecTemp.push_back( a + '0');
269         data.m_vec.pop_back();
270     }
271     return numTemp;
272 }
273 
274 int main()
275 {
276     BigNum numA;
277     BigNum numB;
278     BigNum numC;
279     char opt;
280     while(1){
281         cin >> numA;
282         cin >> opt;
283         cin >> numB;
284         
285         switch(opt){
286         case '+':
287             numC = numA + numB;
288             cout << numC;
289             break;
290         case '-':
291             if(numA == numB){
292                 cout << 0 << endl;
293             }
294             else if(numA > numB){
295                 numC = numA - numB;
296                 cout << numC;
297             }
298             else{
299                 numC = numB - numA;
300                 cout << '-';
301                 cout << numC;
302             }
303             break;
304         case '*':
305             numC = numA * numB;
306             cout << numC;
307             break;
308         case '/':
309             if(numA == numB){
310                 cout << 1 << endl;
311             }
312             else if(numA > numB){
313                 numC = numA / numB;
314                 cout << numC;
315             }
316             else{
317                 cout << 0 << endl;
318             }
319             break;
320         }
321         //清空numA,numB。
322         numA.clr();
323         numB.clr();
324         numC.clr();
325     }
326     return 0;
327 }

 

posted on 2014-04-07 16:50  Allen Blue  阅读(681)  评论(0编辑  收藏  举报

导航