首先咱們先來看以下代碼示例:
public class Test_1 {
public static void main(String[] args) {
System.out.println(0.06+0.01);
System.out.println(1.0-0.42);
System.out.println(4.015*100);
System.out.println(303.1/1000);
}
}
運行結果以下。
0.06999999999999999
0.5800000000000001
401.49999999999994
0.30310000000000004
你認爲你看錯了,但結果倒是是這樣的。問題在哪裏呢?緣由在於咱們的計算機是二進制的。浮點數沒有辦法是用二進制進行精確表示。咱們的CPU表示浮點數由兩個部分組成:指數和尾數,這樣的表示方法通常都會失去必定的精確度,有些浮點數運算也會產生必定的偏差。如:2.4的二進制表示並不是就是精確的2.4。反而最爲接近的二進制表示是 2.3999999999999999。浮點數的值其實是由一個特定的數學公式計算獲得的。
其實java的float只能用來進行科學計算或工程計算,在大多數的商業計算中,通常採用java.math.BigDecimal類來進行精確計算。
在使用BigDecimal類來進行計算的時候,主要分爲如下步驟:
一、用float或者double變量構建BigDecimal對象。
二、經過調用BigDecimal的加,減,乘,除等相應的方法進行算術運算。
三、把BigDecimal對象轉換成float,double,int等類型。
通常來講,可使用BigDecimal的構造方法或者靜態方法的valueOf()方法把基本類型的變量構建成BigDecimal對象。
BigDecimal b1 = new BigDecimal(Double.toString(0.48));
BigDecimal b2 = BigDecimal.valueOf(0.48);
對於經常使用的加,減,乘,除,BigDecimal類提供了相應的成員方法。
public BigDecimal add(BigDecimal value); //加法
public BigDecimal subtract(BigDecimal value); //減法
public BigDecimal multiply(BigDecimal value); //乘法
public BigDecimal divide(BigDecimal value); //除法
進行相應的計算後,咱們可能須要將BigDecimal對象轉換成相應的基本數據類型的變量,可使用floatValue(),doubleValue()等方法。
下面是一個工具類,該工具類提供加,減,乘,除運算。
public class Arith {
/**
* 提供精確加法計算的add方法
* @param value1 被加數
* @param value2 加數
* @return 兩個參數的和
*/
public static double add(double value1, double value2){
BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
return b1.add(b2).doubleValue();
}
/**
* 提供精確減法運算的sub方法
* @param value1 被減數
* @param value2 減數
* @return 兩個參數的差
*/
public static double sub(double www.kunlunyule.com value1, double value2){
BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精確乘法運算的mul方法
* @param value1 被乘數
* @param value2 乘數
* @return 兩個參數的積
*/
public static double mul(double value1, double value2){
BigDecimal b1 = new BigDecimal(www.seocelve.com Double.valueOf(value1));
BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
return b1.multiply(b2).doubleValue(www.chengmingdl.com);
}
/**
* 提供精確的除法運算方法div
* @param value1 被除數
* @param value2 除數
* @param scale 精確範圍
* @return 兩個參數的商
* @throws IllegalAccessException
*/
public static double div(double value1, double value2, int scale) throws IllegalAccessException{
//若是精確範圍小於0,拋出異常信息
if(scale<0){
throw new IllegalAccessException("精確度不能小於0");
}
BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
return b1.divide(b2, scale).doubleValue();
}
/**
* 舍餘
* @param value1 被除數
* @param value2 除數
* @param scale 精確範圍
* @return 兩個參數的商
* @throws IllegalAccessException
*/
public static BigDecimal div2(double value1, double value2, int scale) throws IllegalAccessException{
BigDecimal b1 =www.renheeyuLe.com new BigDecimal(Double.valueOf(value1));
BigDecimal b2 = new BigDecimal(www.renheyL.com Double.valueOf(value2));
return b1.divide(b2, scale, RoundingMode.FLOOR);java