BigDecimal類的簡單用法
一提到Java裡面的商業計算,我們都知道不能用float和double,因為他們無法進行精確計算。但是Java的設計者給程式設計人員提供了一個很有用的類BigDecimal,他可以完善float和double類無法進行精確計算的缺憾。BigDecimal類位於java.maths類包下。首先我們來看下如何構造一個BigDecimal物件。它的建構函式很多,我挑最常用的兩個來演示一下:一個就是BigDecimal(double val),另一個就是BigDecimal(String str)。這兩個看上去沒什麼太大區別,但是正像API描述中說的那樣:
[c-sharp] view plain- /*The results of this constructor can be somewhat unpredictable. One might assume that
- new BigDecimal(.1) is exactly equal to .1, but it is actually equal
- to .1000000000000000055511151231257827021181583404541015625. This is so because .1
-
cannot be represented exactly as a double (or, for that matter, as a binary fraction
- of any finite length). Thus, the long value that is being passed in to the constructor
- is not exactly equal to .1, appearances nonwithstanding.
- The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal
-
(".1") is exactly equal to .1, as one would expect. Therefore, it is generally
- recommended that the (String) constructor be used in preference to this one.*/
也就是說利用double作為引數的建構函式,無法精確構造一個BigDecimal物件,需要自己指定一個上下文的環境,也就是指定精確位。而利用String物件作為引數傳入的建構函式能精確的構造出一個BigDecimal物件。請看下面的程式碼:
[java] view plaincopyprint?- import java.math.*;
- publicclass TestBigDecimal {
- publicstaticvoid main(String args[]){
- BigDecimal bd = new BigDecimal("10.123");
- BigDecimal bd1 = new BigDecimal(10.123);
- System.out.println(bd +"/n"+ bd1);
- }
- }
輸出:
[java] view plaincopyprint?- 10.123
- 10.1229999999999993320898283855058252811431884765625
所以我們在選擇建構函式時,要看具體需求而定。
另外,很多人會問到怎麼將基本型別,如int,float,double,long,和BigDecimal物件相互轉換。很簡單:
基本型別通過建構函式轉換成對應的BigDecimal物件,而BigDecimal類提供了諸如intValue(), floatValue(), doubleValue(), longValue()方法來將BigDecimal物件轉換成對應的值。
關於BigDecimal是如何計算的,我以論壇中一個人的提問帖子為例,來簡單的寫出BigDecimal的運算方法。題目是:李白無事街上走,提壺去買酒。遇店加一倍,見花喝一斗,五遇花和店,喝光壺中酒,試問李白壺中原有多少斗酒?
這道題應該是從後往前推,並且要逆運算,最後得出原有酒的體積。
[java] view plaincopyprint?- import java.math.*;
- publicclass Libai {
- publicstaticvoid main(String args[]){
- BigDecimal volumn = new BigDecimal("0");
- for (int i=0; i<5; i++){
- volumn = volumn.add(new BigDecimal("1"));
- volumn = volumn.divide(new BigDecimal("2"));
- }
- System.out.print(volumn);
- }
- }
結果:
[java] view plaincopyprint?- 0.96875
BufferedImage image = ImageIO.read(new File(jpgPath));
double imageWidth=image.getWidth();
double imageheight=image.getHeight();
double width=1875;
double imageScale=imageWidth/width;
BigDecimal b = new BigDecimal(imageScale);
double fScale = b.setScale(8, BigDecimal.ROUND_HALF_UP).doubleValue();
int newHeight=(int) Math.floor(imageheight/fScale);