java中两个double类型相加抛出异常报错问题的解决方法

来源:互联网 发布:mac cad 看图软件 编辑:程序博客网 时间:2024/05/19 04:51
一:

 Java中的简单浮点数类型float和double不能够进行运算,因为大多数情况下是正常的,但是偶尔会出现如上所示的问题。这个问题其实不是JAVA的bug,因为计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制转化为十进制浮点数时,精度容易丢失,导致精度下降。

  要保证精度就要使用BigDecimal类,而且不能直接从double直接转BigDecimal,要将double转string再转BigDecimal。也就是不能使用BigDecimal(double val) 方法,你会发现没有效果。要使用BigDecimal(String val) 方法。具体例子如下所示。


解决方法一:使用BigDecimal计算辅助类CalculatorUtil


package org.uz.dxt.util;import java.math.BigDecimal;/** * BigDecimal计算辅助类 * @author Duo Nuo * */public class CalculatorUtil {            /**     * ma+mb     * @param ma     * @param mb     * @return     */    public static double pluss(BigDecimal ma, BigDecimal mb){        BigDecimal mc = ma.add(mb);        return  mc.doubleValue();            }        /**     * ma-mb     * @param ma     * @param mb     * @return     */    public static double subtract(BigDecimal ma, BigDecimal mb){        BigDecimal mc = ma.subtract(mb);        return mc.doubleValue();    }        /** * ma+mb * @param ma * @param mb * @param newScale 小数点后保留位数 * @param roundingMode 保留小数模式   BigDecimal.ROUND_DOWN(舍弃)  BigDecimal.ROUND_HALF_UP(四舍五入) * @return */public static BigDecimal plus(BigDecimal ma, BigDecimal mb, int newScale, int roundingMode){BigDecimal mc = ma.add(mb);mc = mc.setScale(newScale, roundingMode);return mc;}/** * ma-mb * @param ma * @param mb * @param newScale 小数点后保留位数 * @param roundingMode 保留小数模式   BigDecimal.ROUND_DOWN(舍弃)  BigDecimal.ROUND_HALF_UP(四舍五入) * @return */public static BigDecimal subtract(BigDecimal ma, BigDecimal mb, int newScale, int roundingMode){BigDecimal mc = ma.subtract(mb);mc = mc.setScale(newScale, roundingMode);return mc;}/** * ma*mb * @param ma * @param mb * @param newScale 小数点后保留位数 * @param roundingMode 保留小数模式   BigDecimal.ROUND_DOWN(舍弃)  BigDecimal.ROUND_HALF_UP(四舍五入) * @return */public static BigDecimal multiply(BigDecimal ma, BigDecimal mb, int newScale, int roundingMode){BigDecimal mc = ma.multiply(mb);mc = mc.setScale(newScale, roundingMode);return mc;}/** * ma/mb * @param ma * @param mb * @param newScale 小数点后保留位数 * @param roundingMode 保留小数模式   BigDecimal.ROUND_DOWN(舍弃)  BigDecimal.ROUND_HALF_UP(四舍五入) * @return */public static BigDecimal divide(BigDecimal ma, BigDecimal mb, int newScale, int roundingMode){BigDecimal mc = ma.divide(mb, newScale, roundingMode);return mc;}/** * Double转为BigDecimal * @param ma * @return */public static BigDecimal DoubleToBigDecimal(Double ma){BigDecimal mb = new BigDecimal(ma.toString());return mb;}/** * BigDecimal转为Double * @param ma * @return */public static Double BigDecimalToDouble(BigDecimal ma){double mb = ma.doubleValue();return mb;}}


使用方法:


Double money1=head.getMoney();Double money2=0.00;if (head.getInterestMoney() != null) {money2=head.getInterestMoney();}//加法Double money=CalculatorUtil.pluss(CalculatorUtil.DoubleToBigDecimal(money1),CalculatorUtil.DoubleToBigDecimal(money2));



解决方法二:


DecimalFormat df  = new DecimalFormat("0.0000");//② 将操作的两个Double类型的数据转换成BigDecimal//例如:Double a1 = 3.4566;Double a2 = 0.2;Double a3 ;BigDecimal b1 = new BigDecimal(df.format(a1));BigDecimal b2 = new BigDecimal(df.format(a2));a3 = b1.add(b2).doubleValue();System.out.println(a3);

谢谢观看

原创粉丝点击