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));
    }
}
唔,其实里面就是一个工具类,加减乘除、保留两位小数。一共5个方法。。。emmmm.....为啥分这么高呢。因为宝宝想分想疯了。 附代码,有土豪就打赏打赏,没土豪的直接拿去使吧。 package cn.cisdom.base.utils; import java.math.BigDecimal; import java.text.DecimalFormat; public class Calculation { public static final DecimalFormat df = new DecimalFormat("######0.00"); /** * @methodName format2point * @desc 保留两位小数点 * @param value * @return java.lang.String * @author xm * @create 2018/6/7 12:03 **/ public static String format2point(Number value) { return df.format(value); } public static Double add(Number value1, Number value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.add(b2).doubleValue(); } /** * 提供精确的减法运算。 * * @param value1 * 减数 * @param value2 * 被减数 * @return 两个参数的差 */ public static Double sub(Number value1, Number value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.subtract(b2).doubleValue(); } /** * 提供精确的乘法运算。 * * @param value1 * 被乘数 * @param value2 * 乘数 * @return 两个参数的积 */ public static Double mul(Number value1, Number value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.multiply(b2).doubleValue(); } /** * 提供精确的除法运算。 * * @param value1 * 除数 * @param value2 * 被除数 * @return 除数/被除数 */ public static Double div(Number value1, Number value2) { //MathContext mc = new MathContext(2, RoundingMode.HALF_DOWN);//精度为2,舍入模式为大于0.5进1,否则舍弃 BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.divide(b2).doubleValue(); } public static void main(String[] args) { Double aDouble=Calculation.add(56.9, 1.67); System.out.println(aDouble); Double bDouble=Calculation.sub(99.2,aDouble); System.out.println(bDouble); } }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员青戈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值