double和float计算精度不准的问题

1、首先我们要知道float和double型,的底层实现是二进制的。十进制中的一个有限位数小数,转换成二进制就不一定是有限位数了,一旦位数超过的float和double型的位数宽度,就会出现“精度溢出”。所以float和double型是为了科学计算而设计的,并不适合精确的十进制计算. 

   例子: 就像一个十进制的小数,要不断地乘以2取整,但在这个过程中可能会一直循环下去,这就造成了数据的不精确。 

所以在必须要求数据的精确度时,不能使用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


BigDecimal类可解决计算精度问题 可使用BigDecimal类创建一个封装类。封装加减乘除操作

例:对一个小数进行指定位数的四舍五入: 

BigDecimal bd = new BigDecimal("0.9851095"); 

BigDecimal one = new BigDecimal("1"); 

System.out.println(bd.divide(one, 3, BigDecimal.ROUND_HALF_UP)); 

BigDecimal中还有很多相关的数值之间的计算方法,以及精确到的位数和四舍五入等。


注意:BigDecimal它的构造函数很多。

我挑最常用的两个 来演示一下:一个就是BigDecimal(double val),另一个就是BigDecimal(String str)。

下面是两个浮点数相减的例子来说明:
public static void main(String[] args) {
double a = 1;
double b = 0.9;
BigDecimal a1 = new BigDecimal(Double.toString(a));
BigDecimal b1 = new BigDecimal(Double.toString(b));
BigDecimal a2 = new BigDecimal(a);
BigDecimal b2 = new BigDecimal(b);
double c = a1.subtract(b1).doubleValue();
double d = a2.subtract(b2).doubleValue();
System.out.println(“c=”+c);
System.out.println(“d=”+d);
}

结果为:
c=0.1
d=0.09999999999999998

可以得出结论:

利用double作为参数的构造函数,无法精确构造一个BigDecimal对象,需要自己指定一个上下文的环境,也就是指定精确位。而利用String对象作为参数传入的构造函数能精确的构造出一个BigDecimal对象。


你可能感兴趣的:(double和float计算精度不准的问题)