java中使用BigDecimal类来实现浮点数的精确运算

在Java中直接对浮点数进行加减乘除运算时会出现精度丢失的问题,如下:

public class Test {
	public static void main(String[] args) {
		System.out.println(0.06+0.01);
		System.out.println(2.0-1.1);
		System.out.println(3.3*3);
		System.out.println(3.3/3);
	}
}

实际的运行结果如下:
0.06999999999999999
0.8999999999999999
9.899999999999999
1.0999999999999999

实际上计算机是二进制的,而浮点数无法通过二进制精确的表示。

浮点数在我们计算机中存储包括三个部分(浮点数的存储请自行百度):
1、符号位(Sign) : 0代表正,1代表为负。
2、指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储。
3、尾数部分(Mantissa):尾数部分。
因此浮点数在计算的时候有时会产生一定的误差,在实际项目中可能需要精确的计算,java中一般采用java.math.BigDecimal类来进行精确的计算。


以下是借用java.math.BigDecimal类来实现double类型数据的加减乘除运算的工具类:

import java.math.BigDecimal;

/**
 * Double类型数据运算工具类(提供精确运算的加减乘除方法)
 * @author 
 *
 */
public class DoubleArithUtil {
	
	/**
	 * 加法运算
	 * @param x 被加数
	 * @param y 加数
	 * @return 两数的和
	 */
	public static double add(double x, double y) {
		BigDecimal vala = new BigDecimal(Double.toString(x));
		BigDecimal valb = new BigDecimal(Double.toString(y));
		return vala.add(valb).doubleValue();
	}
	
	/**
	 * 减法运算
	 * @param x 被减数
	 * @param y 减数
	 * @return 两数的差
	 */
	public static double subtract(double x, double y) {
		BigDecimal vala = new BigDecimal(Double.toString(x));
		BigDecimal valb = new BigDecimal(Double.toString(y));
		return vala.subtract(valb).doubleValue();
	}
	
	/**
	 * 乘法运算
	 * @param x 被乘数
	 * @param y 乘数
	 * @return 两数的积
	 */
	public static double multiply(double x, double y) {
		BigDecimal vala = new BigDecimal(Double.toString(x));
		BigDecimal valb = new BigDecimal(Double.toString(y));
		return vala.multiply(valb).doubleValue();
	}
	
	/**
	 * 除法运算(结果进行四舍五入)
	 * @param x 被除数
	 * @param y 除数
	 * @param scale 小数精确位数
	 * @return 两数的商
	 * @throws ArithmeticException
	 */
	public static double divide(double x, double y, int scale) throws ArithmeticException {
		if (scale < 0) {
			throw new ArithmeticException("精确度不能小于0");
		}
		
		BigDecimal vala = new BigDecimal(Double.toString(x));
		BigDecimal valb = new BigDecimal(Double.toString(y));
		return vala.divide(valb, scale, BigDecimal.ROUND_HALF_EVEN).doubleValue();
	}

}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值