1. 程式人生 > >Exponentiation(求高精度冪)

Exponentiation(求高精度冪)

alt args wan 一位 shu input h+ plain pri

Exponentiation
Time Limit: 500MS Memory Limit: 10000K
Total Submissions: 175340 Accepted: 42341

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

Hint

If you don‘t know how to determine wheather encounted the end of input:
s is a string and n is an integer
C++

while(cin>>s>>n)
{
...
}
c
while(scanf("%s%d",s,&n)==2) //to see if the scanf read in as many items as you want
/*while(scanf(%s%d",s,&n)!=EOF) //this also work */
{
...
}

Source

East Central North America 1988

技術分享圖片

大意:

對數值很大、精度很高的數進行高精度計算是一類十分常見的問題。比如,對國債進行計算就是屬於這類問題。

現在要你解決的問題是:對一個實數R( 0.0 < R < 99.999 ),要求寫程序精確計算 R 的 n 次方(Rn),其中n 是整數並且 0 < n <= 25。

Input

T輸入包括多組 R 和 n。 R 的值占第 1 到第 6 列,n 的值占第 8 和第 9 列。

Output

對於每組輸入,要求輸出一行,該行包含精確的 R 的 n 次方。輸出需要去掉前導的 0 後不要的 0 。如果輸出是整數,不要輸出小數點。

技術分享圖片

解題思路:

(1)pow精度不夠

函數原型:double pow( double x, double y );

頭文件:math.h/cmath(C++中)

功能:計算x的y次方

返回值:x不能為負數且y為小數,或者x為0且y小於等於0,返回冪指數的結果。

1 #include<math.h>  
2 #include<stdio.h>  
3 int main()  
4 {  
5   double x=2.0,y=3.0;  
6   printf("%lf raised to %lf is %lf\n",x,y,pow(x,y));  
7   return 0;  
8 }  

(2)模擬乘法運算過程

  必須自己模擬乘法運算過程,進行高精度的運算。

  題目把輸入的數限制在了6位,即只有5位數字,方便了我們解題。

  我們將輸入數字,以字符串形式讀入,找到小數所在的位數,計算出結果應包含的小數的位數,比如說第一個算式“95.123 12”的小數的位數應該有3*12位。

  解題的關鍵在於進行數據的處理,即模擬整數乘法,使用倒序數組,為什麽使用倒序數組呢?我們模擬一下豎式乘法過程,例如:123*123:

  1 2 3

 x 3

——————

  3 6 9

先用個位乘被乘數;

  1 2 3

 x 2

——————

  2 4 6

  + 3 6 9

——————

  2 7 12 9

在用十位乘被乘數,並相加。

對大於10的進行進位:2 7 12 9 ==》 2 8 2 9

  1 2 3

 x 1

——————

  1 2 3

 + 2 8 2 9

————————

  1 4 11 2 9

在用百位乘被乘數,並相加。

對大於10的進行進位:1 4 11 2 9 ==》 1 5 1 2 9

  從上面的乘法豎式中,我們是向前進位,由於我們不知道最後得到的數據的位數,所以采用倒序存儲,向後進位;從0位開始乘,結果也從0位開始存,非常方便。這樣得出的結果也是倒序的。

  為了計算方便,我們不把數字多余的0去掉,而是在最後判斷小數點的位置,然後輸出該輸出的數位。

  每次乘法,都是用題目給的r乘上你上一次得出的結果,如果是第一次計算,那麽就是r,計算的結果直接加到一個初始化為0的250大小的數組裏面,註意是加。乘法的過程很容易模擬出來,就是讓乘數讓乘數第一位把你的結果的所有位乘一遍,然後再讓第二位乘,註意加進數組時,有一個偏移量,乘法豎式都是這麽寫的,大家體會下。

  開一個250的數組m存儲結果,並且開一個250的數組jieguo存儲中間結果,並且需要一個長度為6的int型數組存儲輸入的String類型的數據r。

  輸出結果時要小心,因為數組中存儲的數位是倒序的,且沒有小數點,需要計算從兩邊向中間的小數點方向第一個不為0數的位置。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<string>
 4 #define MAX 250
 5 using namespace std;
 6 int main()
 7 {
 8     string r;//底數
 9     int n,dian;
10     short Chengshu[6];
11     short m[MAX],jieguo[MAX];
12     while(cin>>r>>n)
13     {
14         for(int i=0;i<=MAX;i++) {m[i]=jieguo[i]=0;}//初始化
15         for(int j=0;j<6;j++) {Chengshu[j]=0;}
16         dian = 0;//小數點位置
17         size_t pos = r.find(".");
18         if(pos != string::npos) dian = (5-pos)*n;
19         for(int i=5,j=0;i>=0;i--)
20         {//註意此處進行倒序存儲
21             if(r[i] != .) {
22                     Chengshu[j] = m[j] = jieguo[j] =  r[i]-0;
23                     //此處要給m[]賦值,當n=1時直接輸出
24                     j++;
25             }
26         }
27         while(n>=2)//當乘冪大於等於2的時候,等於1可直接處理0輸出
28         {
29             for(int i=0;i<MAX;++i) m[i]=0;
30             for(int i=0;i<5;i++)
31             {//chengshu[i]
32                 for(int j=0;j<MAX;j++)
33                 {
34                     if(Chengshu[i]==0) break;
35                     else{
36                         m[i+j] += Chengshu[i]*jieguo[j];
37                         //對>9 的進行處理
38                         for(int t=i+j;m[t]>9;++t)//處理進位
39                         {
40                              m[t+1]+=m[t]/10;
41                              m[t]=m[t]%10;
42                         }
43                     }
44                 }
45             }
46             //更新被乘數
47             for(int k=0;k<MAX;k++)
48             {
49                  jieguo[k] = m[k];
50             }
51             n--;
52         }
53         int first = -1;
54         for(int i=MAX-1;i>=dian;i--)
55         {//從右向左查找第一個不為0的位
56             if(m[i]>0)
57             {
58                 first = i;break;
59             }
60         }
61         int last = dian;
62         for(int j=0;j<dian;j++)
63         {//從左向右查找小數點後第一個不為0的位
64             if(m[j]>0) {
65                 last = j;break;
66             }
67         }
68 
69         if(first != -1)//整數位不全為0
70         {
71             for(int k=first;k>=dian;k--)
72                 cout<<m[k];
73         }
74 
75         if(last != dian)//有小數位
76         {
77             cout<<".";
78             for(int k=dian-1;k>=last;k--)
79                 cout<<m[k];
80         }
81         cout<<endl;
82     }
83     return 0;
84 }

技術分享圖片

java中有一個類 :java.math.BigDecimal

 1 import java.io.*;
 2 import java.util.*;
 3 import java.math.BigDecimal;
 4 
 5 public class Main
 6 {
 7     public static void main(String args[])throws Exception
 8     {
 9         Scanner cin=new Scanner(System.in);
10         while(cin.hasNext())
11         {
12             BigDecimal r=cin.nextBigDecimal();
13             int n=cin.nextInt();
14             r=r.pow(n).stripTrailingZeros();//去掉小數點後面的零
15             String m_string=r.toPlainString();//不帶指數段的字符串表示形式
16             if(m_string.charAt(0)==‘0‘)
17             m_string=m_string.substring(1);
18             System.out.println(m_string);
19         }
20     }
21 }

Exponentiation(求高精度冪)