Java中的精確計算
阿新 • • 發佈:2019-01-11
在Java中,使用類似於下面的方式計算會出現失精度的情況:
//結果為:0.09999999999999998
System.out.println(1-0.9);
這似乎在很多的程式語言中都會遇見。在Java中提供了BigDecimal類用於精確計算,下面是我寫的工具類,這個工具類提供了四種原始運算的精確計算方法,返回的結果都是String型別,這樣更容易表示,也更方便進行二次運算。格式轉換使用的是java.text包中的DecimalFormat類,轉換結果為保留兩位小數的字串數字。碼雲地址:
https://gitee.com/xqnode/java-demo/blob/master/src/utils/decimal/DecimalUtil.java
package utils.decimal;
import java.math.BigDecimal;
import java.text.DecimalFormat;
/**
* 提供精確計算的工具類
*
* @author xiaqing
* @date 2017/11/25.
*/
public class DecimalUtil {
/**
* 格式化輸出結果
*/
private static final DecimalFormat df = new DecimalFormat("0.00");
/**
* 精確的加法
* @param x double型別的數字
* @param y double型別的數字
* @return
*/
public static String add(double x, double y) {
BigDecimal b1 = new BigDecimal(Double.toString(x));
BigDecimal b2 = new BigDecimal(Double.toString(y));
return df.format(b1.add(b2));
}
/**
* 精確的加法
* @param x String型別的數字
* @param y String型別的數字
* @return
*/
public static String add(String x, String y) {
BigDecimal b1 = new BigDecimal(x);
BigDecimal b2 = new BigDecimal(y);
return df.format(b1.add(b2));
}
/**
* 精確的減法
* @param x double型別的數字
* @param y double型別的數字
* @return
*/
public static String subtract(double x, double y) {
BigDecimal b1 = new BigDecimal(Double.toString(x));
BigDecimal b2 = new BigDecimal(Double.toString(y));
return df.format(b1.subtract(b2));
}
/**
* 精確的減法
* @param x String型別的數字
* @param y String型別的數字
* @return
*/
public static String subtract(String x, String y) {
BigDecimal b1 = new BigDecimal(x);
BigDecimal b2 = new BigDecimal(y);
return df.format(b1.subtract(b2));
}
/**
* 精確的乘法
* @param x double型別的數字
* @param y double型別的數字
* @return
*/
public static String multiply(double x, double y) {
BigDecimal b1 = new BigDecimal(Double.toString(x));
BigDecimal b2 = new BigDecimal(Double.toString(y));
return df.format(b1.multiply(b2));
}
/**
* 精確的乘法
* @param x String型別的數字
* @param y String型別的數字
* @return
*/
public static String multiply(String x, String y) {
BigDecimal b1 = new BigDecimal(x);
BigDecimal b2 = new BigDecimal(y);
return df.format(b1.multiply(b2));
}
/**
* 精確的除法
* @param x String型別的數字
* @param y String型別的數字
* @return
*/
public static String divide(double x, double y) {
BigDecimal b1 = new BigDecimal(Double.toString(x));
BigDecimal b2 = new BigDecimal(Double.toString(y));
//scale指的是小數點後的位數,這裡的2表示精確到小數點後面的兩位小數
//roundingMode是小數的保留模式。它們都是BigDecimal中的常量欄位,有很多種。
//比如:BigDecimal.ROUND_HALF_UP表示的就是4舍5入
return df.format(b1.divide(b2,2,BigDecimal.ROUND_HALF_UP));
}
/**
* 精確的乘法
* @param x String型別的數字
* @param y String型別的數字
* @return
*/
public static String divide(String x, String y) {
BigDecimal b1 = new BigDecimal(x);
BigDecimal b2 = new BigDecimal(y);
return df.format(b1.divide(b2,2,BigDecimal.ROUND_HALF_UP));
}
}