解决double转 BigDecimal 时出现的精度失真问题

比如,double dd=344999.03d;
转成 BigDecimal 类型,BigDecimal ss=new BigDecimal(dd);
打印 ss 的值是344999.03000000002793967723846435546875
精度失真啦!

解决方法是
先将 double 转换 字符串,
然后转换成 BigDecimal 。

代码:

/**
* 解决double转bigdecimal时出现的精度问题
 * @param v1
 * @return
 */
public static BigDecimal doubleToBig(double v1) {
	return new BigDecimal(String.valueOf(v1));
}

查询BigDecimal 源码,得出结论:
所有的 基本数字类型(float、double)转换 BigDecimal 或 BigInteger时,

先将 数字类型 先转成字符串,然后再转换BigDecimal 或 BigInteger。

最后,附上 double转 BigDecimal 的工具类

package com.delongra.nback.system.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;


/**
 * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入。
 */
public class DoubleUtil {

	// 默认除法运算精度
	private static final int DEF_DIV_SCALE = 10;
	/**#.## */
	public static final String REG_1 = "#.##";
	/** #,###.## */
	public static final String REG_2 = "#,###.##";

	// 这个类不能实例化
	private DoubleUtil() {
	}

	/**
	 * 解决double转bigdecimal时出现的精度问题
	 * @param v1
	 * @return
	 */
	public static BigDecimal doubleToBig(double v1) {
		return new BigDecimal(String.valueOf(v1));
	}
	
	
	/**
	 * 科学记数法转换成字符串
	 */
	public static String doubleToStr(double v1) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		return b1.toPlainString();
	}
	/**
	 * 科学记数法转换成字符串
	 */
	public static String stringToStr(String v1) {
		BigDecimal b1 = new BigDecimal(v1);
		return b1.toPlainString();
	}
	
	/**
	 * 主要用于格式化金额
	 * @param v1
	 * @return
	 */
	public static String format(double v1) {
		NumberFormat numberFormat = new DecimalFormat(REG_2);
		String str = numberFormat.format(v1);
		return str;
	}
	
	/**
	 * 主要用于格式化小数点
	 * @param v1
	 * @param reg
	 * @return
	 */
	public static String format(double v1,String reg) {
		NumberFormat numberFormat = new DecimalFormat(reg);
		String str = numberFormat.format(v1);
		return str;
	}
	
	
	/**
	 * 加法
	 */
	public static double add(double v1, double ...v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		for (double vv : v2){
			BigDecimal b2 = new BigDecimal(Double.toString(vv));
			b1=b1.add(b2);
		}
		return b1.doubleValue();
	}

	/**
	 * 减法
	 */
	public static double sub(double v1, double ...v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		for (double vv : v2){
			BigDecimal b2 = new BigDecimal(Double.toString(vv));
			b1=b1.subtract(b2);
        }
		
		return b1.doubleValue();
	}

	
	/**
	 * 乘法
	 */
	public static double mul(double v1,double ...v2) {
		BigDecimal b1=new BigDecimal(Double.toString(v1));
		for (double vv : v2){
			BigDecimal b2 = new BigDecimal(Double.toString(vv));
			b1=b1.multiply(b2);
        }
		return b1.doubleValue();
	}

	/**
	 * 除法
	 */

	public static double div(double v1, double ...v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		for (double vv : v2){
			BigDecimal b2 = new BigDecimal(Double.toString(vv));
			b1=b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP);
        }
		return b1.doubleValue();
	}

	/**
	 * 小数的四舍五入
	 */

	public static double round(double v, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException(
					"The   scale   must   be   a   positive   integer   or   zero");
		}
		BigDecimal b = new BigDecimal(Double.toString(v));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}
	
	/**
	 * 两个数比较,获取比较值相对于基准值的大小百分比
	 * @param base 基准值
	 * @param compare 比较值
	 * @return
	 */
	public static String getComparePercent(int base,int compare){
		if (base==compare) {
			return "0%";
		}
		if (compare==0) {
			return "0%";
		}
		if (base==0) {
			return compare*100+"%";
		}
        NumberFormat numberFormat = NumberFormat.getInstance();  
        numberFormat.setMaximumFractionDigits(2); // 设置精确到小数点后2位  
        int margin = compare-base;
        String result = numberFormat.format((float) margin / (float) base * 100);  
		return result + "%";
	}	
}

猜你喜欢

转载自blog.csdn.net/xiaojin21cen/article/details/83345771