Java中的精确计算

来源:互联网 发布:无效的json字符串 编辑:程序博客网 时间:2024/05/16 18:22

在Java中,使用类似于下面的方式计算会出现失精度的情况:

//结果为:0.09999999999999998System.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));    }}