问题案例
由于计算机系统的特性,java浮点数(float、double)的精度有时候会不准确,案例代码如下:
System.out.println(0.09 + 0.01);
System.out.println(1.0 - 0.32);
System.out.println(1.015 * 100);
System.out.println(1.301 / 100);
输出结果
输出结果
发生了计算结果精度有误差的问题
解决办法
利用BigDecimal类(包:java.math.BigDecimal)解决计算误差问题
- 1、加减乘解决办法
BigDecimal类创建对象时有多个重载方法,推荐使用参数为String的构造方法创建对象进行计算,因为String可以表示无限长度的数,而int、long、float等表示的数的范围是有限的,代码如下:
/** 加 */
BigDecimal b1 = new BigDecimal("0.09");
BigDecimal b2 = new BigDecimal("0.01");
BigDecimal bigAdd = b1.add(b2);
System.out.println(bigAdd);
/** 减 */
BigDecimal b3 = new BigDecimal("1");
BigDecimal b4 = new BigDecimal("0.32");
BigDecimal bigSub = b3.subtract(b4);
System.out.println(bigSub);
/** 乘 */
BigDecimal b5 = new BigDecimal("1.015");
BigDecimal b6 = new BigDecimal("100");
BigDecimal bigMul = b5.multiply(b6);
System.out.println(bigMul);
输出结果
输出结果
- 2、除解决方法
为什么除与加减乘不一样,因为除会涉及到除不尽的问题,小数点后是无限的,所以它不知道该如何显示,就会抛出异常,例如:
BigDecimal b1 = new BigDecimal("1.301");
BigDecimal b2 = new BigDecimal("101");
BigDecimal bigDiv = b1.divide(b2);
System.out.println(bigDiv);
输出结果
输出结果
所以应该用divide()的一个重载方法:public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode),来设置精确到多少位:
/** 除
* 参数1:被除数
* 参数2:精确到第N位
* 参数3:N位后的数的取舍方式,填BigDecimal定义好的常量
* 通常用以下三个常量:
* ROUND_HALF_UP 表示N位后的那一位四舍五入
* ROUND_UP 表示N位后的那一位直接入
* ROUND_DOWN 表示N位后的那一位直接舍
* 当然,取舍完后,第N位之后的通通丢弃
*/
BigDecimal b1 = new BigDecimal("1.301");
BigDecimal b2 = new BigDecimal("101");
//精确到第5位
BigDecimal bigDiv = b1.divide(b2,5,BigDecimal.ROUND_HALF_UP);
//精确到第4位,第5位四舍五入
BigDecimal bigDiv1 = b1.divide(b2,4,BigDecimal.ROUND_HALF_UP);
//精确到第4位,第5位直接入
BigDecimal bigDiv2 = b1.divide(b2,4,BigDecimal.ROUND_UP);
//精确到第4位,第5位直接舍
BigDecimal bigDiv3 = b1.divide(b2,4,BigDecimal.ROUND_DOWN);
System.out.println(bigDiv);
System.out.println(bigDiv1);
System.out.println(bigDiv2);
System.out.println(bigDiv3);
输出结果
输出结果
网友评论