java中float,double类型运算的处理

public class Test{
    public static void main(String args[]){
        System.out.println(0.05+0.01);
        System.out.println(1.0-0.42);
        System.out.println(4.015*100);
        System.out.println(123.3/100);
    }
}

你没有看错!结果确实是

0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999

Java中的浮点数类型float和double不能够进行运算,因为大多数情况下是正常的,但是偶尔会出现如上所示的问题。

这个问题其实不是JAVA的bug,因为计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制转化为十进制浮点数时,精度容易丢失,导致精度下降。

java专门的小数运算类:BigDecimal类型,用于解决double和float小数运算更精准的计算。

根据平时工作需要,写了一个工作类,方便使用:

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() {
	}
	
	

	/**
	 * 去掉科学记数法
	 */
	public static String toStr(double v1) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		return b1.toPlainString();
	}
	
	/**
	 * 主要用于格式化金额
	 * @param v1 如:56,888,458,521
	 * @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();
	}

	/**
	 *除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
	

	public static double div(double v1, double ...v2) {
		return div(DEF_DIV_SCALE,v1, v2);
	} */

	/**
	 * 提供(相对)精确的除法运算。
	 */

	public static double div(double v1, double ...v2) {
//		if (scale < 0) {
//			throw new IllegalArgumentException(
//					"The   scale   must   be   a   positive   integer   or   zero");
//		}
		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();
	}
	
	
	public static String doubleWangFormatByObj(Object obj){
		return doubleWangFormatByObj(obj, "0");
	}
	
	public static String doubleWangFormatByObj(Object obj,String defaultValue){
		if(obj==null){
			return defaultValue;
		}else{
			DecimalFormat df = new DecimalFormat("0.00");
			return df.format(((Double)obj)/10000);
		}
	}
	
	public static String doubleFormatByObj(Object obj,String defaultValue){
		if(obj==null){
			return defaultValue;
		}else{
			DecimalFormat df = new DecimalFormat("0.00");
			return df.format(((Double)obj));
		}
	}
	
	public static void main(String[] args) {
		double sum=0;
		
		System.out.println(DoubleUtil.doubleFormatByObj(sum,"0.00"));
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值