1. 程式人生 > >Java中的精確計算

Java中的精確計算

在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)); } }