基于C++STL——超级高精度浮点数大数计算
这个代码是借鉴其他作者的BigInteger计算方案,然后自己进行改动,使其能够计算浮点数的+-*/四则运算,并且支持int数作为幂数计算一个浮点数的乘方,接口都是重载的运算符,通过加载.h文件,定义BigFloat对象,就可以进行计算,由于使用的是vector进行存储和计算,所以计算的精度很高。
#define ACCURACY 100
是定义浮点数除法的计算精度,代表了迭代次数,通过增加这个数值,可以进一步增加计算精度。
程序已经通过基本的测试,如有程序有问题请不吝赐教,转载请注明出处。
参考:http://blog.csdn.net/touzani/article/details/1749256
程序主体,在这里定义了BigFloat类以及异常类,在此基础上,重载了计算需要的几个基本的运算符,使得主函数可以通过包含这个文件完成大数计算。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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对象的构造,然后调用重载的运算符进行计算。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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