关于double/float 两种基本类型精度丢失的总结
现在是2017年8月26号19:点37分,上周有我最好的朋友来找我,忙着聊天没有时间写博客,现在我补写一篇,算是我十年博客的第五周,好了,言归正传,今天我想记录的是java类中double/float关于精度丢失的问题!
首先,我想让大家看一段代码:
1 public static void main(String[] args) { 2 3 System.out.println("0.05+0.01="+(0.05+0.01)); 4 System.out.println("1.0-0.42="+(1.0-0.42)); 5 System.out.println("4.015*100="+(4.015*100)); 6 System.out.println("123.3/100="+(123.3/100)); 7 8 }
很意外,最后返回的结果是:
为什么java语言返回之后结果不是我们预料的结果呢?事实上,不光java语言,C语言、C++等众多语言,都存在这种精度丢失的现象,整数永远可以用二进制精确表示 ,但小数就不一定了。关于精度丢失的具体原理,我就不在这里一一述说了,附上一篇文章,有兴趣可以查看:
http://www.cnblogs.com/yewsky/articles/1864934.html
那么有没有方法可以避免精度丢失的情况呢?当然有,我在这里介绍java当中的一种类:BigDecimal,在平常的开发中使用java.math.BigDecimal类来进行精确计算。
在使用BigDecimal类来进行计算的时候,主要分为以下步骤:
1、用float或者double变量构建BigDecimal对象。
2、通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算。
3、把BigDecimal对象转换成float,double,int等类型。
一般来说,可以使用BigDecimal的构造方法或者静态方法的valueOf()方法把基本类型的变量构建成BigDecimal对象。
BigDecimal b1 = new BigDecimal(Double.toString(0.48)); BigDecimal b2 = BigDecimal.valueOf(0.48);
最后,我用上面的代码案例说明,做一个结尾
1 public static void main(String[] args) { 2 3 BigDecimal b1 = new BigDecimal("0.05"); 4 BigDecimal b2 = BigDecimal.valueOf(0.01); 5 6 System.out.println("0.05+0.01="+b1.add(b2)); 7 System.out.println("0.05-0.01="+b1.subtract(b2)); 8 System.out.println("0.05*0.01="+b1.multiply(b2)); 9 System.out.println("0.05/0.01="+b1.divide(b2)); 10 11 }
最后输出的结果是:
备注:
创建BigDecimal对象时,不要直接使用double浮点数作为构造器参数来调用BigDecimal构造器,否则同样会发生精度丢失的问题