Java中的精确计算

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

//结果为:0.09999999999999998
System.out.println(1-0.9);

这似乎在很多的编程语言中都会遇见。在Java中提供了BigDecimal类用于精确计算,下面是我写的工具类,这个工具类提供了四种原始运算的精确计算方法,返回的结果都是String类型,这样更容易表示,也更方便进行二次运算。格式转换使用的是java.text包中的DecimalFormat类,转换结果为保留两位小数的字符串数字。

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

你可能感兴趣的:(java)