基于C++STL——超级高精度浮点数大数计算

这个代码是借鉴其他作者的BigInteger计算方案,然后自己进行改动,使其能够计算浮点数的+-*/四则运算,并且支持int数作为幂数计算一个浮点数的乘方,接口都是重载的运算符,通过加载.h文件,定义BigFloat对象,就可以进行计算,由于使用的是vector进行存储和计算,所以计算的精度很高。

define ACCURACY 100

是定义浮点数除法的计算精度,代表了迭代次数,通过增加这个数值,可以进一步增加计算精度。

程序已经通过基本的测试,如有程序有问题请不吝赐教,转载请注明出处。

参考:http://blog.csdn.net/touzani/article/details/1749256

程序主体,在这里定义了BigFloat类以及异常类,在此基础上,重载了计算需要的几个基本的运算符,使得主函数可以通过包含这个文件完成大数计算。
基于C++STL——超级高精度浮点数大数计算基于C++STL——超级高精度浮点数大数计算View Code

1 //MyBigFloat.h
  2  
  3  #include <deque>
  4  #include <vector>
  5  #include <iostream>
  6  #include <string>
  7  #include <algorithm>
  8  using namespace std;
  9  #define ACCURACY 100
 10  
 11  
 12      class DividedByZeroException{
 13      public:
 14          void error(){cout<<"Divided By Zero Exception!"<<endl;}
 15      };
 16      class BigFloat{
 17      private:
 18              vector<char> integer;
 19              vector<char> decimal;
 20              void trim();
 21              bool tag;
 22      public:
 23              
 24              BigFloat(int);    // construct with a int integer
 25              BigFloat(string&) ;
 26              BigFloat();
 27              BigFloat(const BigFloat&);
 28              BigFloat operator=(const BigFloat& op);
 29  
 30              BigFloat      abs() const;
 31              BigFloat      pow(int a);
 32  
 33              //binary operators
 34              
 35              friend BigFloat operator+(const BigFloat&,const BigFloat&);
 36              friend BigFloat operator-(const BigFloat&,const BigFloat&);
 37              friend BigFloat operator*(const BigFloat&,const BigFloat&);
 38              friend BigFloat operator/(const BigFloat&,const BigFloat&) throw(DividedByZeroException); 
 39  
 40              friend BigFloat operator-(const BigFloat&);   //negative
 41  
 42              friend bool operator==(const BigFloat&,const BigFloat&);
 43              friend bool operator==(const BigFloat&,const BigFloat&);
 44              friend bool operator<(const BigFloat&,const BigFloat&);
 45              friend bool operator<=(const BigFloat&,const BigFloat&);
 46              friend bool operator>(const BigFloat&,const BigFloat&);
 47              friend bool operator>=(const BigFloat&,const BigFloat&);
 48  
 49              friend BigFloat operator+=(BigFloat&,const BigFloat&);
 50              friend BigFloat operator-=(BigFloat&,const BigFloat&);
 51              friend BigFloat operator*=(BigFloat&,const BigFloat&);
 52              friend BigFloat operator/=(BigFloat&,const BigFloat&) throw(DividedByZeroException);
 53  
 54              friend ostream& operator<<(ostream&,const BigFloat&);    //print the BigInteger
 55              friend istream& operator>>(istream&, BigFloat&);         // input the BigInteger
 56  
 57      public:
 58              static const BigFloat ZERO;
 59              static const BigFloat ONE;
 60              static const BigFloat TEN;
 61      };
 62      BigFloat operator-(const BigFloat& op)
 63      {
 64          BigFloat temp(op);
 65          temp.tag = !temp.tag;
 66          return temp;
 67      }
 68      void BigFloat::trim() {
 69          vector<char>::reverse_iterator iter = integer.rbegin();
 70          while(!integer.empty() && (*iter) == 0){
 71              integer.pop_back();
 72              iter=integer.rbegin();
 73          }
 74          if( integer.size()==0 ) {
 75              tag = true;
 76              integer.push_back(0);
 77          }
 78          vector<char>::const_iterator it = decimal.begin();
 79          while(!decimal.empty() && (*it) == 0){
 80              it = decimal.erase(it);
 81          }
 82          if( decimal.size()==0 ) {
 83              tag = true;
 84              decimal.push_back(0);
 85          }
 86      }
 87      //delete those 0 in the front
 88       const BigFloat BigFloat::ZERO=BigFloat(0);
 89       const BigFloat BigFloat::ONE =BigFloat(1);
 90       const BigFloat BigFloat::TEN =BigFloat(10);
 91  
 92       BigFloat::BigFloat(int val){
 93           if (val >= 0)
 94              tag = true;
 95          else{
 96              tag = false;
 97              val *= (-1);
 98          }
 99          do{
100              integer.push_back( (char)(val%10) );
101              val /= 10;
102          } while ( val != 0 );
103          decimal.push_back(0);
104       }
105  
106       BigFloat::BigFloat( ){
107          tag = true;
108          integer.push_back(0);
109          decimal.push_back(0);
110       }
111  
112  
113       BigFloat::BigFloat(string& def){
114          bool type = true;
115          for(string::reverse_iterator iter = def.rbegin() ; iter < def.rend();  iter++)
116          {
117              char ch = (*iter);
118              if(ch == '.'){
119                  type = false;
120                  iter++;
121              }
122              if (iter == def.rend()-1){
123                  if ( ch == '+' )
124                      break;
125                  if(ch == '-' ){
126                      tag = false;
127                      break;
128                  }
129              }
130              //在此处使用string的逆向迭代器,将整个数据从后往前进行处理。
131              if(type)decimal.push_back( (char)((*iter) - '0' ) );
132              else integer.push_back( (char)((*iter) - '0' ) );
133          }
134       }
135  
136      BigFloat::BigFloat(const BigFloat &op)
137      {
138          integer = op.integer;
139          decimal = op.decimal;
140          tag = op.tag;
141      }
142  
143      BigFloat BigFloat::operator=(const BigFloat& op)
144      {
145          integer = op.integer;
146          decimal = op.decimal;
147          tag = op.tag;
148          return (*this);
149      }
150  
151      BigFloat BigFloat::abs() const  {
152          if(tag)  return (*this);
153          else      return -(*this);
154      }
155      //
156      BigFloat BigFloat::pow(int a) 
157       {
158          BigFloat res(1);
159          for(int i=0; i<a; i++)
160              res*=(*this);
161          return res;
162      }
163  
164      ostream& operator<<(ostream& stream,const BigFloat& val){    //print the BigInteger
165          if (!val.tag)
166              stream << "-";    
167          for ( vector<char>::const_reverse_iterator iter = val.integer.rbegin(); iter != val.integer.rend() ; iter++)
168              stream << (char)((*iter) + '0');  
169          cout<<'.';
170          for ( vector<char>::const_reverse_iterator iter = val.decimal.rbegin(); iter != val.decimal.rend() ; iter++)
171              stream << (char)((*iter) + '0');
172          return stream;
173      }
174  
175      istream& operator>>(istream& stream, BigFloat& val){    //Input the BigInteger
176          string str;
177          stream >> str;
178          val=BigFloat(str);
179          return stream;
180      }
181  
182      BigFloat operator+=(BigFloat& op1,const BigFloat& op2){
183          if( op1.tag == op2.tag ) {     //只处理相同的符号的情况,异号的情况给-处理
184              vector<char>::iterator iter1;
185              vector<char>::const_iterator iter2,it;
186      //处理小数部分
187              int a = op1.decimal.size();
188              int b = op2.decimal.size();
189              char to_add = 0;     //进位
190              if(a<b){
191                  iter1 = op1.decimal.begin();
192                  iter2 = op2.decimal.begin();
193                  iter2 = iter2 - (a-b);
194                     
195              while ( iter1 != op1.decimal.end() && iter2 != op2.decimal.end()){
196                  (*iter1) = (*iter1) + (*iter2) + to_add;
197                  to_add = ((*iter1) > 9);    // 大于9进一位
198                  (*iter1) = (*iter1) % 10;
199                  iter1++; iter2++;
200              }
201                  it = op2.decimal.begin();
202                  iter2 = op2.decimal.end();
203                  iter2 = iter2 - a -1;
204                  while(iter2 != it){
205                      op1.decimal.insert(op1.decimal.begin(),*iter2);
206                      iter2--;
207                  }//此处应该用反向迭代器
208                  op1.decimal.insert(op1.decimal.begin(),*iter2);
209                  iter1 = op1.decimal.begin();
210              }
211              else if(a>b){
212                  iter1 = op1.decimal.begin();
213                  iter1 = iter1+(a-b);
214                  iter2 = op2.decimal.begin();
215                  while ( iter1 != op1.decimal.end() && iter2 != op2.decimal.end()){
216                      (*iter1) = (*iter1) + (*iter2) + to_add;
217                      to_add = ((*iter1) > 9);    // 大于9进一位
218                      (*iter1) = (*iter1) % 10;
219                      iter1++; iter2++;
220                  }
221              }
222              else {
223                  iter1 = op1.decimal.begin();
224                  iter2 = op2.decimal.begin();
225                  while ( iter1 != op1.decimal.end() && iter2 != op2.decimal.end()){
226                      (*iter1) = (*iter1) + (*iter2) + to_add;
227                      to_add = ((*iter1) > 9);    // 大于9进一位
228                      (*iter1) = (*iter1) % 10;
229                      iter1++; iter2++;
230                  }
231              }
232              
233      //处理整数部分
234              iter1 = op1.integer.begin();
235              iter2 = op2.integer.begin();
236              //进位
237              while ( iter1 != op1.integer.end() && iter2 != op2.integer.end()){
238                  (*iter1) = (*iter1) + (*iter2) + to_add;
239                  to_add = ((*iter1) > 9);    // 大于9进一位
240                  (*iter1) = (*iter1) % 10;
241                  iter1++; iter2++;
242              }
243              while ( iter1 != op1.integer.end() ){   // 
244                  (*iter1) = (*iter1) + to_add;
245                  to_add = ( (*iter1) > 9 );
246                  (*iter1) %= 10;
247                  iter1++;
248              }
249              while ( iter2 != op2.integer.end() ){
250                  char val = (*iter2) + to_add;
251                  to_add = (val > 9) ;
252                  val %= 10;
253                  op1.integer.push_back(val);
254                  iter2++;
255              }
256              if( to_add != 0 )
257                  op1.integer.push_back(to_add);
258              return op1;
259          }
260          else{
261              if (op1.tag)
262                  return op1 -= (-op2);
263              else
264                  return op1= op2 - (-op1);
265          }
266      }
267      ////
268      BigFloat operator-=(BigFloat& op1,const BigFloat& op2){
269          if( op1.tag == op2.tag ) {     //只处理相同的符号的情况,同号的情况给+处理
270              if(op1.tag)  { 
271                  if(op1 < op2)  // 2 - 3
272                  {
273                      BigFloat op(op2 - op1);
274                      op1 = -op;
275                      return op1;//
276                  }
277              } 
278              else {
279                  if(-op1 > -op2)  // (-3)-(-2) = -(3 - 2)
280                      return op1=-((-op1)-(-op2));
281                  else             // (-2)-(-3) = 3 - 2 
282                      return op1= (-op2) - (-op1);
283              }
284      //小数部分 
285              char to_substract = 0;  //借位
286              int a = op1.decimal.size();
287              int b = op2.decimal.size();
288              vector<char>::iterator it1 = op1.decimal.begin();
289              vector<char>::const_iterator it2 = op2.decimal.begin();
290              if(a>b){
291                  a -= b;
292                  it1 = it1 + a;
293              }
294              else{
295                  int number = b-a;
296                  while(number!=0)
297                  {
298                      op1.decimal.insert(op1.decimal.begin(),'0');//should be insert into the head of the vector
299                      number--;
300                  }
301              }
302              while ( it1 != op1.decimal.end() && it2 != op2.decimal.end()) {
303                      (*it1) = (*it1) - (*it2) - to_substract;
304                      to_substract = 0;
305                      if( (*it1) < 0 ) {
306                          to_substract=1;
307                          (*it1) += 10;
308                      }
309                      it1++;
310                      it2++;
311                  }
312      //整数部分
313              vector<char>::iterator iter1;
314              vector<char>::const_iterator iter2;
315              iter1 = op1.integer.begin();
316              iter2 = op2.integer.begin();
317  
318              while ( iter1 != op1.integer.end() && iter2 != op2.integer.end()) {
319                  (*iter1) = (*iter1) - (*iter2) - to_substract;
320                  to_substract = 0;
321                  if( (*iter1) < 0 ) {
322                      to_substract=1;
323                      (*iter1) += 10;
324                  }
325                  iter1++;
326                  iter2++;
327              }
328              while ( iter1 != op1.integer.end() ) {
329                  (*iter1) = (*iter1) - to_substract;
330                  to_substract = 0;
331                  if( (*iter1) < 0 ) {
332                      to_substract=1;
333                      (*iter1) += 10;
334                  }
335                  else break;
336                  iter1++;
337              }
338              op1.trim();
339              return op1;
340          }//符号相同
341          else {
342              if (op1 > BigFloat::ZERO)
343                  return op1 += (-op2);
344              else
345                  return op1 = -(op2 + (-op1));
346          }
347      }
348      BigFloat operator*=(BigFloat& op1,const BigFloat& op2) {
349          BigFloat result(0);
350          if (op1 == BigFloat::ZERO || op2==BigFloat::ZERO)
351              result = BigFloat::ZERO;
352          else{
353              int size = 0;
354              vector<char> op_temp1(op1.integer.begin(), op1.integer.end());
355              if(op1.decimal.size()!=1||(op1.decimal.size()==1&&(*op1.decimal.begin())!=0)){
356                  op_temp1.insert(op_temp1.begin(),op1.decimal.begin(), op1.decimal.end());
357                  size += op1.decimal.size();
358              }
359              vector<char> op_temp2(op2.integer.begin(), op2.integer.end());
360              if(op2.decimal.size()!=1||(op2.decimal.size()==1&&(*op2.decimal.begin())!=0)){
361                  op_temp2.insert(op_temp2.begin(),op2.decimal.begin(), op2.decimal.end());
362                  size += op2.decimal.size();
363              }
364              vector<char>::const_iterator iter2 = op_temp2.begin();
365              while( iter2 != op_temp2.end() ){
366                  if(*iter2 != 0){
367                      deque<char> temp(op_temp1.begin() , op_temp1.end());
368                      char to_add = 0;
369                      deque<char>::iterator iter1 = temp.begin();
370                      while( iter1 != temp.end() ){
371                          (*iter1) *= (*iter2);
372                          (*iter1) += to_add;
373                          to_add = (*iter1) / 10;
374                          (*iter1) %= 10;
375                          iter1++;
376                      }//while
377                      if( to_add != 0)
378                          temp.push_back( to_add );
379                      int num_of_zeros = iter2 - op_temp2.begin();
380                      while(  num_of_zeros--)
381                          temp.push_front(0);
382                      BigFloat temp2;
383                      temp2.integer.clear();
384                      temp2.integer.insert( temp2.integer.end() , temp.begin() , temp.end() );
385                      temp2.trim();
386                      result = result + temp2;
387                      //
388                  }//if
389                  iter2++;
390              }//while
391              result.tag = ( (op1.tag && op2.tag) || (!op1.tag && !op2.tag) );
392              if(size!=0){
393                  result.decimal.clear();
394                  result.decimal.insert(result.decimal.begin(), result.integer.begin(), result.integer.begin()+size);
395                  result.integer.erase(result.integer.begin(), result.integer.begin()+size);
396              }
397          }//else
398          op1 = result;
399          return op1;
400      }
401      BigFloat operator/=(BigFloat& op1,const BigFloat& op2){
402          if(op2 == BigFloat::ZERO)
403              throw DividedByZeroException();
404          if(op1 == BigFloat::ZERO)
405              return op1;
406          BigFloat op_temp2 = op2;
407          BigFloat op_temp1 = op1;
408          int Integer_Size = 0;
409          if((op_temp2.decimal.size() == 1)&&(*(op_temp2.decimal.begin()) == 0)){    }
410          else{
411              //Integer_Size -= op_temp2.decimal.size();
412              int t = op_temp2.decimal.size();
413              while(t--){
414                  op_temp1 = op_temp1*BigFloat::TEN;
415                  op_temp2 = op_temp2*BigFloat::TEN;
416              }
417          }
418          if(op_temp1<op_temp2){
419              while(op_temp1>op_temp2){
420                  op_temp1 *= BigFloat::TEN;
421                  Integer_Size--;
422              }
423          }
424          else{
425              while(op_temp1>op_temp2){
426                  op_temp1.decimal.push_back(*op_temp1.integer.begin());
427                  op_temp1.integer.erase(op_temp1.integer.begin());
428                  Integer_Size++;
429              }
430          }
431          int k = ACCURACY;
432          BigFloat re(0); 
433          while(k--){
434              if(op_temp1<op_temp2){
435                  op_temp1 = op_temp1*BigFloat::TEN;
436                  re = re*BigFloat::TEN;
437              }
438              else{
439                  int i;
440                  BigFloat compare;
441                  for(i=2;i<10;i++){
442                      BigFloat BF(i);
443                      compare = op_temp2*BF;
444                      if(compare>op_temp1)
445                          break;
446                  }//for
447                  compare -= op_temp2;
448                   op_temp1 -= compare;
449                  BigFloat index(i-1);
450                  re = re + index;
451              }//else
452          }//while    
453          if(re.integer.size()>Integer_Size){
454              vector<char> temp(re.integer.begin(), re.integer.end());
455              re.integer.assign(temp.end() - Integer_Size, temp.end());
456              re.decimal.insert(re.decimal.begin(), temp.begin(),temp.end() - Integer_Size);
457          }
458          else{
459              int t = Integer_Size - re.integer.size();
460              while(t--){
461                  re = re*BigFloat::TEN;
462              }
463          }
464          
465          op1 = re;
466          op1.trim();
467          op1.tag = ( (op1.tag && op2.tag) || (!op1.tag && !op2.tag) );
468          return op1;
469      }
470      BigFloat operator+(const BigFloat& op1,const BigFloat& op2){
471          BigFloat temp(op1);
472          temp += op2;
473          return temp;
474      }
475      BigFloat operator-(const BigFloat& op1,const BigFloat& op2){
476          BigFloat temp(op1);
477          temp -= op2;
478          return temp;
479      }
480      BigFloat operator*(const BigFloat& op1,const BigFloat& op2){
481          BigFloat temp(op1);
482          temp *= op2;
483          return temp;
484      }
485      BigFloat operator/(const BigFloat& op1,const BigFloat& op2){
486          BigFloat temp(op1);
487          temp /= op2;
488          return temp;
489      }
490      bool operator<(const BigFloat& op1,const BigFloat& op2){
491          bool sign;
492          if( op1.tag != op2.tag ){
493              sign =  !op1.tag;    
494              return sign;
495          }
496          else{
497              if(op1.integer.size() != op2.integer.size()){
498                  if(op1.tag){
499                      sign = op1.integer.size()<op2.integer.size();            
500                      return sign;
501                  }
502                  else {
503                      sign = op1.integer.size()>op2.integer.size();
504                      return sign;
505                  }
506              } 
507              vector<char>::const_reverse_iterator iter1,iter2;
508              iter1 = op1.integer.rbegin();
509              iter2 = op2.integer.rbegin();
510              while( iter1 != op1.integer.rend() ){
511                  if(  op1.tag &&  *iter1 < *iter2 ) return true;
512                  if(  op1.tag &&  *iter1 > *iter2 ) return false;
513                  if( !op1.tag &&  *iter1 > *iter2 ) return true;
514                  if( !op1.tag &&  *iter1 < *iter2 ) return false;
515                  iter1++;
516                  iter2++;
517              }
518              vector<char>::const_reverse_iterator it1,it2;
519              it1 = op1.decimal.rbegin();
520              it2 = op2.decimal.rbegin();
521              while( it1 != op1.decimal.rend() && it2 != op2.decimal.rend()){
522                  //cout<<((*it1)+'0')<<((*it1)+'0')<<endl;
523                  if(  op1.tag &&  *it1 < *it2 ) return true;
524                  if(  op1.tag &&  *it1 > *it2 ) return false;
525                  if( !op1.tag &&  *it1 > *it2 ) return true;
526                  if( !op1.tag &&  *it1 < *it2 ) return false;
527                  it1++;
528                  it2++;
529              }
530              return (op1.tag && it2!=op2.decimal.rend())
531                  || (!op1.tag && it1!=op1.decimal.rend());
532          }
533      }
534      bool operator>(const BigFloat& op1,const BigFloat& op2){
535          bool tag = !(op1<=op2);
536          return tag;
537      }
538      bool operator==(const BigFloat& op1,const BigFloat& op2){
539          if(op1.tag == (!op2.tag)){
540               return false;
541          }
542          //这里十分奇怪,因为两个标记都是true的时候,t得到的结果是false,然后if判断的时候确又视为true
543          if(op1.integer.size() != op2.integer.size() ){
544               return false;
545          }
546          if( op1.decimal.size() != op2.decimal.size() ){
547              return false;
548          }
549          vector<char>::const_iterator iter1,iter2;
550          iter1 = op1.decimal.begin();
551          iter2 = op2.decimal.begin();
552          while( iter1!= op1.decimal.end() ){
553              if( *iter1 != *iter2 )  return false;
554              iter1++;
555              iter2++;
556          }
557          iter1 = op1.integer.begin();
558          iter2 = op2.integer.begin();
559          while( iter1!= op1.integer.end() ){
560              if( *iter1 != *iter2 )  return false;
561              iter1++;
562              iter2++;
563          }
564          return true;
565      }
566  
567      bool operator!=(const BigFloat& op1,const BigFloat& op2){
568          return !(op1==op2);
569      }
570      bool operator>=(const BigFloat& op1,const BigFloat& op2){
571          bool tag = (op1>op2) || (op1==op2);   
572          return tag;
573      }
574  
575      bool operator<=(const BigFloat& op1,const BigFloat& op2){
576          bool tag = (op1<op2) || (op1==op2);
577          return tag;
578      }

主函数,通过string进行BigFloat对象的构造,然后调用重载的运算符进行计算。
基于C++STL——超级高精度浮点数大数计算基于C++STL——超级高精度浮点数大数计算View Code

1 // local ---main.cpp
 2  #include <iostream>
 3  #include "MyBigFloat.h"
 4  using namespace std;
 5  int main(){
 6      string a1,b1;
 7      while(cin>>a1>>b1)
 8      {    
 9          BigFloat A(a1),B(b1);
10          cout<<"A-B:"<<A-B<<endl;
11          cout<<"A+B:"<<A+B<<endl;
12          cout<<"A*B:"<<A*B<<endl;
13          try{
14              cout<<"A/B:"<<A/B<<endl;
15          } catch(DividedByZeroException &e)
16          {
17              e.error();
18          }
19          cout<<"A.pow(5)"<<A.pow(5)<<endl;
20      }
21      return 0;
22  }

运行结果:

123412341234123412341234123412341289430984095.8328452930854923984721374109578034

120934789347523984502394852389459832.348983043051234

A-B:123412341113188622993710138909946437041524263.4838622500342583984721374109578034

A+B:123412341355058201688758107914736141820443928.1818283361367263984721374109578034

A*B:14924845490033463033898914676326982698074993523391988034588218499567596427331814.809641834199892

1022587550531865460632407582993956

A/B:1020486676.0331653553081055068709102382482090343238

A.pow(5)28628128412193762632283891530939841343168592366257014410600105853097135939848993236111288312

6450197703319404013899529470095476904373255803641674804002333253942118080971709470799437300353000285

66710540595386752293726346582.0724672123661347915902660230379338198139229303406991774583154916142091

5876633409235831344641926311649259994882785659624994652044053598269422357142694631100862140536475424
原文链接: https://www.cnblogs.com/wangbiaoneu/archive/2013/04/25/My_Big_Float.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/85869

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午10:17
下一篇 2023年2月9日 下午10:17

相关推荐