1、實際意義 在實際開發中,如果需要進行float或double的精確計算(尤其是財務計算),直接使用float或double是不行的(具體的例子看下邊的代碼的main方法的測試結果),需要使用BigDecimal。 2、代碼 package com.xxx.util; import java.ma
1、實際意義
在實際開發中,如果需要進行float或double的精確計算(尤其是財務計算),直接使用float或double是不行的(具體的例子看下邊的代碼的main方法的測試結果),需要使用BigDecimal。
2、代碼
package com.xxx.util; import java.math.BigDecimal; /** * 浮點數精準演算法 */ public class BigDecimalArithUtil { private static final int DIV_SCALE = 10;//除法精度(除不盡時保留10為小數) /** 小數精確加法 */ public static double add(double d1,double d2) { BigDecimal bd1 = BigDecimal.valueOf(d1); BigDecimal bd2 = BigDecimal.valueOf(d2); return bd1.add(bd2).doubleValue(); } /** 小數精確減法 */ public static double sub(double d1,double d2) { BigDecimal bd1 = BigDecimal.valueOf(d1); BigDecimal bd2 = BigDecimal.valueOf(d2); return bd1.subtract(bd2).doubleValue(); } /** 小數精確乘法 */ public static double mul(double d1,double d2) { BigDecimal bd1 = BigDecimal.valueOf(d1); BigDecimal bd2 = BigDecimal.valueOf(d2); return bd1.multiply(bd2).doubleValue(); } /** 小數精確除法 */ public static double div(double d1,double d2) { BigDecimal bd1 = BigDecimal.valueOf(d1); BigDecimal bd2 = BigDecimal.valueOf(d2); /* * 當除不盡時,以四捨五入的方式(關於除不盡後的值的處理方式有很多種)保留小數點後10位小數 */ return bd1.divide(bd2, DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue(); } public static void main(String[] args) { //測試加法 System.out.println("0.05+0.01="+BigDecimalArithUtil.add(0.05,0.01)); System.out.println("0.05+0.01="+(0.05+0.01)); //測試減法 System.out.println("1.0-0.42="+BigDecimalArithUtil.sub(1.0,0.42)); System.out.println("1.0-0.42="+(1.0-0.42)); //測試乘法 System.out.println("4.015*100="+BigDecimalArithUtil.mul(4.015,100)); System.out.println("4.015*100="+(4.015*100)); //測試除法 System.out.println("123.3/100="+BigDecimalArithUtil.div(123.3,100)); System.out.println("123.3/100="+(123.3/100)); } }View Code
3、註意點
- 上邊的程式我用的是BigDecimal.valueOf(double x)來將double型的x封裝成BigDecimal,查看源碼如下:
/** * 註意:這通常是將double和float轉換為一個BigDecimal的最好方式 */ public static BigDecimal valueOf(double val) { return new BigDecimal(Double.toString(val)); }
View Code在這裡直接先將double轉換為了String,然後使用如下構造方法再將String轉換為BigDecimal
public BigDecimal(String val)
這是最好的做法。如果使用的是直接將double或float轉換為BigDecimal的方式,也就是說使用的如下構造器,那麼將可能得不到精確結果。(看註釋)
/** * 註意:The results of this constructor can be somewhat unpredictable. * 該構造器的結果有時是不准確的 */ public BigDecimal(double val)
View Code - 在實際使用中還可能使用int和long來進行浮點數的精確計算(具體做法:將浮點數先乘以相應的倍數轉化為int(<=9位十進位數)或long(<=18位十進位數),計算之後再除以之前的倍數,得出結果),而且該種方式的性能會更高,具體的int、long和BigDecimal各自的使用看《Effective Java(第二版)》第48條。
- 需要指出的是,在實際開發中,BigDecimal的性能差的問題基本可以忽略,是浮點數精確計算的首選,而且根據上一條來看,如果將浮點數轉化後的整數大於18位的話,也必須用BigDecimal