这个代码是借鉴其他作者的BigInteger计算方案,然后自己进行改动,使其能够计算浮点数的+-*/四则运算,并且支持int数作为幂数计算一个浮点数的乘方,接口都是重载的运算符,通过加载.h文件,定义BigFloat对象,就可以进行计算,由于使用的是vector进行存储和计算,所以计算的精度很高。
define ACCURACY 100
是定义浮点数除法的计算精度,代表了迭代次数,通过增加这个数值,可以进一步增加计算精度。
程序已经通过基本的测试,如有程序有问题请不吝赐教,转载请注明出处。
参考:http://blog.csdn.net/touzani/article/details/1749256
程序主体,在这里定义了BigFloat类以及异常类,在此基础上,重载了计算需要的几个基本的运算符,使得主函数可以通过包含这个文件完成大数计算。
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对象的构造,然后调用重载的运算符进行计算。
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
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!