來看一道題(http://poj.org/problem?id=1001),如下:
Exponentiation
Time Limit: 500MS | Memory Limit: 10000K | |
Total Submissions: 111481 | Accepted: 27078 |
Description
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
Output
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
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
開始採用Java的double數據類型,始終計算不精確。
查閱資料後,想到Java中的BigDecimal數據類型。
來看看JDK中關於BigDecimal的描述——
public class BigDecimalextends Numberimplements Comparable<BigDecimal>
不可變的、任意精度的有符號十進制數。BigDecimal 由任意精度的整數非標度值 和 32 位的整數標度 (scale) 組成。如果爲零或正數,則標度是小數點後的位數。如果爲負數,則將該數的非標度值乘以 10 的負 scale 次冪。因此,BigDecimal 表示的數值是(unscaledValue × 10-scale)。
BigDecimal 類提供以下操作:算術、標度操作、舍入、比較、哈希算法和格式轉換。toString()
方法提供BigDecimal 的規範表示形式。 public BigDecimal(double val)
- 將 double 轉換爲 BigDecimal,後者是 double 的二進制浮點值準確的十進制表示形式。返回的BigDecimal 的標度是使
(10scale × val) 爲整數的最小值。
注:
- 此構造方法的結果有一定的不可預知性。有人可能認爲在 Java 中寫入new BigDecimal(0.1) 所創建的 BigDecimal 正好等於 0.1(非標度值 1,其標度爲 1),但是它實際上等於 0.1000000000000000055511151231257827021181583404541015625。這是因爲 0.1 無法準確地表示爲double(或者說對於該情況,不能表示爲任何有限長度的二進制小數)。這樣,傳入 到構造方法的值不會正好等於 0.1(雖然表面上等於該值)。
- 另一方面,String 構造方法是完全可預知的:寫入new BigDecimal("0.1") 將創建一個 BigDecimal,它正好 等於預期的 0.1。因此,比較而言,通常建議優先使用String 構造方法。
- 當double 必須用作
BigDecimal 的源時,請注意,此構造方法提供了一個準確轉換;它不提供與以下操作相同的結果:先使用
Double.toString(double)
方法,然後使用BigDecimal(String)
構造方法,將double 轉換爲 String。要獲取該結果,請使用 staticvalueOf(double)
方法。
- 參數:
val
- 要轉換爲 BigDecimal 的 double 值。- 拋出:
NumberFormatException
- 如果 val 爲無窮大或 NaN。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
因此可以,採用BigDecimal進行計算,構造方法傳入參數爲String類型即可。
import java.math.BigDecimal;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (true) {
try {
double a = scan.nextDouble();
int b = scan.nextInt();
System.out.println(trim0(myPower(a, b).toPlainString()));
} catch (Exception e) {
return;
}
}
}
public static BigDecimal myPower(double num, int n) {
BigDecimal a = new BigDecimal(String.valueOf(num));
BigDecimal res = new BigDecimal("1.0");
for (int i = 0; i < n; i++) {
res = res.multiply(a);
}
return res;
}
public static String trim0(String data) {
int startPos = 0, endPos = data.length() - 1;
while (data.charAt(startPos) == '0')
startPos++;
while (data.charAt(endPos) == '0')
endPos--;
if (data.indexOf('.') == endPos)
endPos--;
return data.substring(startPos, endPos + 1);
}
}