高精度幂

来源:互联网 发布:python自动化运维 pdf 编辑:程序博客网 时间:2024/05/22 10:51
  1. /* 
  2.  *********************************** 
  3.  *    Time  : 2017/8/31 
  4.  *    Author:liuwei  
  5.  *    Problem:  http://poj.org/problem?id=1001 
  6.  *    Problem Description :[double] power of [integer], the length of result is long  
  7.  *********************************** 
  8. */  
  9. #include<iostream>  
  10. #include<string.h>  
  11. #include<math.h>  
  12. using namespace std ;  
  13.   
  14. #define MAX_LENGTH 100  //数组长度  
  15. #define MAX_VALUE 1000    //每个int表示的不可达上界   
  16. #define MAX_SYS  3      //MAX_VALUE = pow(10,MAX_SYS)  
  17. /*定义大整数类*/  
  18. class BigInteger  
  19. {  
  20. public:  
  21.     /*double直接扩大n倍,去掉小数点*/  
  22.     BigInteger(char s[] , int size)  
  23.     : index(0)  
  24.     {  
  25.         for(int y = 0 ;y<MAX_LENGTH ; y++)  
  26.             num[y] = 0 ;  
  27.         int  j = 0 ;  
  28.         for(int i = size -1 ; i>= 0 ;i--)  
  29.         {  
  30.               
  31.             if(s[i]=='.')  
  32.                 continue ;  
  33.             if(j != MAX_SYS)  
  34.                 num[index] += (s[i] - '0')*pow(10,j);  
  35.             else   
  36.             {  
  37.                 num[++index] += s[i] - '0' ;  
  38.                 j = 0 ;  
  39.             }  
  40.             ++j ;   
  41.         }  
  42.   
  43.     }  
  44.     /*默认值为0初始化*/  
  45.     BigInteger()  
  46.     : index(0)   
  47.     {  
  48.         for(int y = 0 ;y<MAX_LENGTH ; y++)  
  49.             num[y] = 0 ;  
  50.     }  
  51.     /*默认值为i(i<1000)初始化*/  
  52.     BigInteger(int i )  
  53.     :  index(0)  
  54.     {  
  55.         for(int y = 0 ;y<MAX_LENGTH ; y++)  
  56.             num[y] = 0 ;  
  57.         num[0] = i ;  
  58.     }   
  59.     //大整数相加  
  60.     friend BigInteger operator+(const BigInteger &B1 ,const BigInteger &B2)  
  61.     {  
  62.         int i  = 0 ;  
  63.         BigInteger p ;  
  64.         int valuePlus = 0 ;  
  65.         int value = 0 ;  
  66.         int addition = 0 ;  
  67.         int max_index = B1.getIndex() > B2.getIndex() ? B1.getIndex() :B2.getIndex() ;   
  68.         while(i<=max_index)  
  69.         {  
  70.             valuePlus = B1.getValue(i)+B2.getValue(i) + addition;  
  71.             value = valuePlus%MAX_VALUE ;  
  72.             p.setValue(i,value);   
  73.             if(value != valuePlus)   //进1   
  74.                 addition = 1 ;  
  75.             else   
  76.                 addition = 0 ;  
  77.             ++i ;  
  78.               
  79.         }  
  80.         if(addition != 0)  
  81.             p.setValue(i,addition);  
  82.         return p ;  
  83.     }  
  84.     //大整数相乘  
  85.     friend BigInteger operator*(const BigInteger &B1 , const BigInteger &B2)  
  86.     {  
  87.         int i = B1.getIndex();  
  88.         int j = B2.getIndex();  
  89.         BigInteger  Bs ;  
  90.         BigInteger  Btemp ;  
  91.         int addition = 0 ;  
  92.         int valueMulti = 0 ;  
  93.         int value = 0 ;  
  94.         int is , js ;  
  95.         /*按照乘法规则进行*/  
  96.         for( is = 0 ; is <= i ; ++is)  
  97.         {  
  98.             for( js = 0 ; js<= j ; ++js)  
  99.             {  
  100.                 valueMulti = B2.getValue(js)*B1.getValue(is) + addition ;  
  101.                 value = valueMulti%MAX_VALUE ;  
  102.                 addition = (int)(valueMulti/MAX_VALUE) ;  
  103.                 Btemp.setValue(js+is,value) ;     
  104.             }  
  105.             if(addition!=0)  
  106.             {  
  107.                 Btemp.setValue(js+is,addition);  
  108.                 addition = 0 ;  
  109.             }  
  110.               
  111.             Bs = Bs+Btemp ;  
  112.             Btemp.clear();    
  113.         }  
  114.         return Bs ;                   
  115.     }   
  116.       
  117.     //基本的get() set()   
  118.     void setValue(int ind , int value)  
  119.     {  
  120.         if(ind>index)  /*若是新的快有了数据,要设置index*/  
  121.             index = ind ;  
  122.         num[ind] = value ;  
  123.     }  
  124.     int  getValue(int index)const  
  125.     {  
  126.         return num[index] ;  
  127.     }  
  128.     int getIndex()const  
  129.     {  
  130.         return index ;  
  131.     }  
  132.       
  133.     void print()               //不带小数点的大整数输出   
  134.     {  
  135.         int g = MAX_SYS ;  
  136.         int j = 0 ;   
  137.         for(j = index ; j>= 0 ; j--)    
  138.         {  
  139.                 g = MAX_SYS ;  
  140.                 while( num[j] < pow(10,g-1)  && g>1 && j!=index)   //增添0,比如某个块值为1,则应该打印出001   
  141.                 {                                              //但是最开始的不增添0   
  142.                     cout<<"0";  
  143.                     g--;   
  144.                 }  
  145.                 cout<<num[j];  
  146.         }  
  147.           
  148.         cout<<endl;  
  149.     }   
  150.     /*清空数据*/  
  151.     void clear()  
  152.     {  
  153.         while(index>=0)  
  154.             num[index--] = 0 ;  
  155.     }  
  156.     //输出大整数到屏幕   
  157.     void print(int pos)       //带有小数点的大整数输出   
  158.     {  
  159.         int countIndex = pos/MAX_SYS ;  //找到小数点位于num[]的下标   
  160.         int oneOfThree = pos%MAX_SYS ;  //确定小数点在num[countIndex]的下标   
  161.         int i = 0 ;           
  162.         int j = 0 ;  
  163.         int g = MAX_SYS ;                
  164.         int max_cin = countIndex > index ? countIndex:index ;  //处理0.00000001与112.00005的情况   
  165.         if(countIndex > index)     //若是0.000014,则先输出小数点   
  166.             cout<<"." ;   
  167.         /*下面分两种情况,一个是小数点位于num[]块间,一个是在块内*/  
  168.         if(oneOfThree == 0)  //恰好在块间   
  169.         {   
  170.             for(j = max_cin;j>=countIndex;j--)   //整数部分,增添0,比如某个块值为1              
  171.             {                                     //  则应该打印出001,必须是三位数   
  172.                 g = MAX_SYS ;  
  173.                 while( num[j] < pow(10,g-1)  && g>1 && j!=max_cin) //第一个除外 ,1就是输出1   
  174.                 {  
  175.                     cout<<"0";  
  176.                     g--;   
  177.                 }  
  178.                 cout<<num[j];  
  179.             }  
  180.             if(countIndex <= index)      //输出小数点   
  181.                 cout<<".";  
  182.             while(j>=0)            //输出小数部分   
  183.             {   
  184.                 g = MAX_SYS ;  
  185.                 while( num[j] < pow(10,g-1)  && g>1 )  //也是补0,够三位数   
  186.                 {  
  187.                     cout<<"0";  
  188.                     g--;   
  189.                 }  
  190.                 cout<<num[j];  
  191.                 j-- ;  
  192.             }     
  193.         }  
  194.         else     //小数点在块内   
  195.         {  
  196.             for(j = max_cin; j>countIndex; j--)    //整数部分   
  197.             {  
  198.                 g = MAX_SYS ;  
  199.                 while( num[j] < pow(10,g-1)  && g>1 && j!=max_cin )  
  200.                 {  
  201.                     cout<<"0";  
  202.                     g--;   
  203.                 }  
  204.                 cout<<num[j] ;  
  205.             }  
  206.             /*输出块内*/  
  207.             if(countIndex<=index)     
  208.             {  
  209.                 int k = oneOfThree -1 ;  
  210.                 cout<<(int)(num[j]/(int)pow(10,oneOfThree));  
  211.                 cout<<".";  
  212.                 while(k >= 0)  
  213.                 {  
  214.                     cout<<(int)(num[j]/pow(10,k))%10;  
  215.                     k--;  
  216.                 }  
  217.             }  
  218.             if(countIndex > index)   //小数点就位于这个块内,只是看看要补几个0的事情   
  219.             {  
  220.                 int k = oneOfThree ;  
  221.                 while(k-- > 0)  
  222.                 {  
  223.                     cout<<"0";  
  224.                 }  
  225.             }  
  226.             j--;    //别漏了   
  227.             while(j>=0)   //小数部分   
  228.             {  
  229.                 g = MAX_SYS ;  
  230.                 while( num[j] < pow(10,g-1)  && g>1)  
  231.                 {  
  232.                     cout<<"0";  
  233.                     g--;   
  234.                 }  
  235.                 cout<<num[j];  
  236.                 j-- ;  
  237.             }     
  238.         }  
  239.         cout<<endl ;    //这个不写,就会出现PE,不给通过   
  240.     }  
  241. private:  
  242.     int num[MAX_LENGTH] ; //数据   
  243.     int index  ;     //数据最大下标   
  244. };  
  245.   
  246. //去除尾0,找到小数点位置   
  247. int foo(char c[] , int size_C , int cn )//全局函数,传递数组、数组长度、以及指数    
  248. {  
  249.     int i = 0 ;  
  250.       
  251.     for( i = size_C - 1  ; i>=0  ; --i)//去除尾 0  (一定是带有小数点的字符串)  
  252.     {  
  253.         if(c[i]=='0')     
  254.         {  
  255.             c[i] = '\0' ;  
  256.         }  
  257.         else  
  258.           break ;  
  259.     }   
  260.       
  261.     int np = 0 ;     //小数点位数   
  262.       
  263.     for( i = strlen(c)-1 ; i>=0; --i) //统计小数点位数   
  264.     {  
  265.         if(c[i] != '.')  
  266.             ++np ;  
  267.         else  
  268.          break ;  
  269.     }  
  270.     return np*cn ;//最终小数位数   
  271. }  
  272. /**/  
  273. int main(int argc , char *args[])  
  274. {  
  275.    char s[10] ;  
  276.    int  n;  
  277.      
  278.    int i = 0 ;  
  279.    int Dpoint ;  //标志最终输出小数还是整数   
  280.     
  281.    while(cin>>s>>n)  
  282.    {  
  283.         Dpoint  = foo(s,strlen(s),n) ;  
  284.         BigInteger Bs(s,strlen(s)) ;  
  285.         BigInteger Bn(1) ;  
  286.         for(i=0 ; i<n ; ++i)  
  287.         {  
  288.             Bn = Bn*Bs ;  
  289.         }  
  290.               
  291.       
  292.         if(Dpoint!=0)  
  293.             Bn.print(Dpoint);  
  294.         else  
  295.             Bn.print() ;  
  296.     }  
  297.     return 0 ;  
  298. }  
原创粉丝点击