【原】 POJ 1001 Exponentiation 大整数乘法 解题报告

http://poj.org/problem?id=1001

 
方法:
大整数乘法
这题没什么好说的,直接用字符串模拟整个过程

 

Description

Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems.
This problem requires that you write a program to compute the exact value of Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.

Input

The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.

Output

The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.

Sample Input

95.123 12

0.4321 20

5.1234 15

6.7592 9

98.999 10

1.0100 12

Sample Output

548815620517731830194541.899025343415715973535967221869852721

.00000005148554641076956121994511276767154838481760200726351203835429763013462401

43992025569.928573701266488041146654993318703707511666295476720493953024

29448126.764121021618164430206909037173276672

90429072743629540498.107596019456651774561044010001

1.126825030131969720661201

 
   1: #include <iostream>
   2: #include <string>
   3:  
   4: using namespace std ;
   5:  
   6: //大浮点数相乘,此时系统提供的精度远远不能达到要求
   7:  
   8: string multiply_bignum(const string& lhs,const string& rhs)
   9: {
  10:     //if( lhs=="0" || rhs=="0" )
  11:     //    return "0" ;
  12:  
  13:     //lengths of the two operators , including dot
  14:     size_t len1 = lhs.size() ;
  15:     size_t len2 = rhs.size() ;
  16:     int index=0 ;
  17:  
  18:     //carefully judge whether exist 0
  19:     //.000 or 0.000 or 000.
  20:     for( index=0 ; index<len1 ; ++index)
  21:     {
  22:         if( lhs[index]!='0' && lhs[index]!='.' )
  23:             break;
  24:     }
  25:     if( index==len1 )
  26:         return "0" ;
  27:  
  28:     for( index=0 ; index<len2 ; ++index)
  29:     {
  30:         if( rhs[index]!='0' && rhs[index]!='.' )
  31:             break;
  32:     }
  33:     if( index==len2 )
  34:         return "0" ;
  35:  
  36:     //copy the two operators , because later may delete their dots
  37:     string s1(lhs);
  38:     string s2(rhs);    
  39:     //max length of the result
  40:     size_t lenResult = len1+len2 ;
  41:  
  42:     int val1,val2,tmpval,mul_carry,sum_carry ;
  43:     int i,j,k,t,m ;
  44:  
  45:     //initialize the result to 0
  46:     string result(lenResult,'0') ;    
  47:  
  48:     size_t dotnum1,dotnum2,dotnumResult;
  49:     //find the positions of the dots in the two operators
  50:     string::size_type pos1 = s1.find(".") ;
  51:     string::size_type pos2 = s2.find(".") ;
  52:     string::size_type dotpos ;
  53:  
  54:     if( pos1 == string::npos )   //there is no dot
  55:         dotnum1 = 0 ;
  56:     else                         //the operator is float
  57:     {
  58:         s1.erase( pos1 , 1 ) ;   //delete the dot , 12.34-->1234
  59:         dotnum1 = len1-pos1-1 ;  //number of the digit behind the dot
  60:         --len1 ;                 //now the length decrease 1
  61:     }
  62:  
  63:     if( pos2 == string::npos )
  64:         dotnum2 = 0 ;
  65:     else
  66:     {
  67:         s2.erase( pos2 , 1 ) ;
  68:         dotnum2 = len2-pos2-1 ;
  69:         --len2 ;
  70:     }
  71:  
  72:     dotnumResult = dotnum1+dotnum2 ;    //number of digit behind the dot in the result
  73:     dotpos = lenResult-dotnumResult-1 ; //the position of the dot in the result
  74:  
  75:     for( i=len2-1 , k=lenResult-1 ; i>=0 ; --i ,--k )  //s1*s2
  76:     {
  77:         string tmpresult(lenResult,'0') ;
  78:         mul_carry = 0 ;    //carry of multiply in calculating the tmpresult
  79:         sum_carry = 0 ;    //carry of sum in calculating the final result
  80:         val2 = s2[i]-'0';  //get the digit of s2 in reverse order to simulate the process of multiply
  81:  
  82:         for( j=len1-1 , t=k ; j>=0 ; --j , --t )
  83:         {
  84:             val1 = s1[j]-'0' ;
  85:             tmpval = val1*val2 + mul_carry ;
  86:             mul_carry = tmpval/10 ;
  87:             tmpresult[t] = tmpval - 10*mul_carry + '0' ;
  88:         }
  89:         tmpresult[t] = mul_carry + '0' ;  //put the final carry to the tmpresult
  90:  
  91:         for( m=lenResult-1 ; m>=0 ; --m ) //update the result
  92:         {
  93:             tmpval = (result[m]-'0') + (tmpresult[m]-'0') + sum_carry ;
  94:             sum_carry = tmpval/10 ;
  95:             result[m] = tmpval - 10*sum_carry + '0' ;
  96:         }
  97:     }
  98:     string::size_type resultBeginPos ;
  99:     string::size_type resultEndPos ;
 100:     if( dotnumResult == 0 )  //there is no dot
 101:     {
 102:         resultBeginPos = result.find_first_not_of('0') ;
 103:         return result.substr(resultBeginPos); ;
 104:     }
 105:     else
 106:     {
 107:         result.insert( ++dotpos , 1 , '.' );  //insert the dot into result
 108:  
 109:         resultBeginPos = result.find_first_not_of('0') ;
 110:         resultEndPos = result.find_last_not_of('0') ;
 111:         if( resultBeginPos == dotpos )  //0.123000
 112:             return result.substr( resultBeginPos , resultEndPos-resultBeginPos+1 ) ;
 113:         else if( resultBeginPos < dotpos ) //12.3400 or 12340.0000
 114:         {
 115:             if( resultEndPos > dotpos )  //12.3400
 116:                 return result.substr( resultBeginPos , resultEndPos-resultBeginPos+1 ) ;
 117:             if( resultEndPos == dotpos )  //12340.0000
 118:                 return result.substr( resultBeginPos , resultEndPos-resultBeginPos );
 119:         }    
 120:     }
 121: }
 122:  
 123: //divide and conquer
 124: string power_bignum(const string& R,int n)
 125: {
 126:     if(n==0)
 127:         return "1" ;
 128:     if(R=="0")
 129:         return "0" ;
 130:  
 131:     if(n==1)
 132:         return multiply_bignum( R , "1" ) ;
 133:     string tmpresult = power_bignum(R,n/2);
 134:     if( n%2 != 0 )
 135:         return multiply_bignum( R , multiply_bignum(tmpresult,tmpresult) );
 136:     else
 137:         return multiply_bignum(tmpresult,tmpresult) ;
 138: }
 139:  
 140: void run1001()
 141: {
 142:     string r;
 143:     int n;
 144:     while(cin>>r>>n)
 145:         cout<<power_bignum(r,n)<<endl;
 146: }
posted @ 2010-11-04 19:57  Allen Sun  阅读(463)  评论(0编辑  收藏  举报