高精度幂

xiaoxiao2021-02-28  107

/*   ***********************************   *    Time  : 2017/8/31   *    Author:liuwei    *    Problem:  http://poj.org/problem?id=1001   *    Problem Description :[double] power of [integer], the length of result is long    ***********************************  */   #include<iostream>   #include<string.h>   #include<math.h>   using namespace std ;      #define MAX_LENGTH 100  //数组长度   #define MAX_VALUE 1000    //每个int表示的不可达上界    #define MAX_SYS  3      //MAX_VALUE = pow(10,MAX_SYS)   /*定义大整数类*/   class BigInteger   {   public:       /*double直接扩大n倍,去掉小数点*/       BigInteger(char s[] , int size)       : index(0)       {           for(int y = 0 ;y<MAX_LENGTH ; y++)               num[y] = 0 ;           int  j = 0 ;           for(int i = size -1 ; i>= 0 ;i--)           {                              if(s[i]=='.')                   continue ;               if(j != MAX_SYS)                   num[index] += (s[i] - '0')*pow(10,j);               else                {                   num[++index] += s[i] - '0' ;                   j = 0 ;               }               ++j ;            }          }       /*默认值为0初始化*/       BigInteger()       : index(0)        {           for(int y = 0 ;y<MAX_LENGTH ; y++)               num[y] = 0 ;       }       /*默认值为i(i<1000)初始化*/       BigInteger(int i )       :  index(0)       {           for(int y = 0 ;y<MAX_LENGTH ; y++)               num[y] = 0 ;           num[0] = i ;       }        //大整数相加       friend BigInteger operator+(const BigInteger &B1 ,const BigInteger &B2)       {           int i  = 0 ;           BigInteger p ;           int valuePlus = 0 ;           int value = 0 ;           int addition = 0 ;           int max_index = B1.getIndex() > B2.getIndex() ? B1.getIndex() :B2.getIndex() ;            while(i<=max_index)           {               valuePlus = B1.getValue(i)+B2.getValue(i) + addition;               value = valuePlus%MAX_VALUE ;               p.setValue(i,value);                if(value != valuePlus)   //进1                    addition = 1 ;               else                    addition = 0 ;               ++i ;                          }           if(addition != 0)               p.setValue(i,addition);           return p ;       }       //大整数相乘       friend BigInteger operator*(const BigInteger &B1 , const BigInteger &B2)       {           int i = B1.getIndex();           int j = B2.getIndex();           BigInteger  Bs ;           BigInteger  Btemp ;           int addition = 0 ;           int valueMulti = 0 ;           int value = 0 ;           int is , js ;           /*按照乘法规则进行*/           for( is = 0 ; is <= i ; ++is)           {               for( js = 0 ; js<= j ; ++js)               {                   valueMulti = B2.getValue(js)*B1.getValue(is) + addition ;                   value = valueMulti%MAX_VALUE ;                   addition = (int)(valueMulti/MAX_VALUE) ;                   Btemp.setValue(js+is,value) ;                  }               if(addition!=0)               {                   Btemp.setValue(js+is,addition);                   addition = 0 ;               }                              Bs = Bs+Btemp ;               Btemp.clear();             }           return Bs ;                        }               //基本的get() set()        void setValue(int ind , int value)       {           if(ind>index)  /*若是新的快有了数据,要设置index*/               index = ind ;           num[ind] = value ;       }       int  getValue(int index)const       {           return num[index] ;       }       int getIndex()const       {           return index ;       }              void print()               //不带小数点的大整数输出        {           int g = MAX_SYS ;           int j = 0 ;            for(j = index ; j>= 0 ; j--)             {                   g = MAX_SYS ;                   while( num[j] < pow(10,g-1)  && g>1 && j!=index)   //增添0,比如某个块值为1,则应该打印出001                    {                                              //但是最开始的不增添0                        cout<<"0";                       g--;                    }                   cout<<num[j];           }                      cout<<endl;       }        /*清空数据*/       void clear()       {           while(index>=0)               num[index--] = 0 ;       }       //输出大整数到屏幕        void print(int pos)       //带有小数点的大整数输出        {           int countIndex = pos/MAX_SYS ;  //找到小数点位于num[]的下标            int oneOfThree = pos%MAX_SYS ;  //确定小数点在num[countIndex]的下标            int i = 0 ;                    int j = 0 ;           int g = MAX_SYS ;                         int max_cin = countIndex > index ? countIndex:index ;  //处理0.00000001与112.00005的情况            if(countIndex > index)     //若是0.000014,则先输出小数点                cout<<"." ;            /*下面分两种情况,一个是小数点位于num[]块间,一个是在块内*/           if(oneOfThree == 0)  //恰好在块间            {                for(j = max_cin;j>=countIndex;j--)   //整数部分,增添0,比如某个块值为1                           {                                     //  则应该打印出001,必须是三位数                    g = MAX_SYS ;                   while( num[j] < pow(10,g-1)  && g>1 && j!=max_cin) //第一个除外 ,1就是输出1                    {                       cout<<"0";                       g--;                    }                   cout<<num[j];               }               if(countIndex <= index)      //输出小数点                    cout<<".";               while(j>=0)            //输出小数部分                {                    g = MAX_SYS ;                   while( num[j] < pow(10,g-1)  && g>1 )  //也是补0,够三位数                    {                       cout<<"0";                       g--;                    }                   cout<<num[j];                   j-- ;               }              }           else     //小数点在块内            {               for(j = max_cin; j>countIndex; j--)    //整数部分                {                   g = MAX_SYS ;                   while( num[j] < pow(10,g-1)  && g>1 && j!=max_cin )                   {                       cout<<"0";                       g--;                    }                   cout<<num[j] ;               }               /*输出块内*/               if(countIndex<=index)                  {                   int k = oneOfThree -1 ;                   cout<<(int)(num[j]/(int)pow(10,oneOfThree));                   cout<<".";                   while(k >= 0)                   {                       cout<<(int)(num[j]/pow(10,k));                       k--;                   }               }               if(countIndex > index)   //小数点就位于这个块内,只是看看要补几个0的事情                {                   int k = oneOfThree ;                   while(k-- > 0)                   {                       cout<<"0";                   }               }               j--;    //别漏了                while(j>=0)   //小数部分                {                   g = MAX_SYS ;                   while( num[j] < pow(10,g-1)  && g>1)                   {                       cout<<"0";                       g--;                    }                   cout<<num[j];                   j-- ;               }              }           cout<<endl ;    //这个不写,就会出现PE,不给通过        }   private:       int num[MAX_LENGTH] ; //数据        int index  ;     //数据最大下标    };      //去除尾0,找到小数点位置    int foo(char c[] , int size_C , int cn )//全局函数,传递数组、数组长度、以及指数     {       int i = 0 ;              for( i = size_C - 1  ; i>=0  ; --i)//去除尾 0  (一定是带有小数点的字符串)       {           if(c[i]=='0')              {               c[i] = '\0' ;           }           else             break ;       }               int np = 0 ;     //小数点位数               for( i = strlen(c)-1 ; i>=0; --i) //统计小数点位数        {           if(c[i] != '.')               ++np ;           else            break ;       }       return np*cn ;//最终小数位数    }   /**/   int main(int argc , char *args[])   {      char s[10] ;      int  n;            int i = 0 ;      int Dpoint ;  //标志最终输出小数还是整数            while(cin>>s>>n)      {           Dpoint  = foo(s,strlen(s),n) ;           BigInteger Bs(s,strlen(s)) ;           BigInteger Bn(1) ;           for(i=0 ; i<n ; ++i)           {               Bn = Bn*Bs ;           }                                 if(Dpoint!=0)               Bn.print(Dpoint);           else               Bn.print() ;       }       return 0 ;   }  
转载请注明原文地址: https://www.6miu.com/read-50757.html

最新回复(0)