前言
说到Java浮点数新手第一想到的就是使用double。有些人知道Java中double类型与float类型的精度不同,计算时精度会发生丢失甚至错误。
我也知道小数使用double与float会造成精度问题,但是一直都没有关心到底应该如何解决,最近工作中碰到了一个上千万的小数计算,才发现使用double计算小数不仅仅精度会错,在数值过大的情况下会变成科学计数法表示。
1.double与float
public static void main(String[] args) {
// Java中小数默认为double类型
System.out.println(100000000000000.0 + 0.9);
Double double1 = 100000000000000.0d + 0.9d;
System.out.println(double1.toString());
Float float1 = 100000000000000.0f + 0.9f;
System.out.println(float1.toString());
Double double2 = (double) (100000000000000.0f + 0.9f);
System.out.println(double2.toString());
}
结果:
1.000000000000009E14
1.000000000000009E14
1.0E14
1.00000000376832E14
2.BigDecimal
可以看出关于大小数的计算使用double与float不仅会使精度丢失还会变成科学计数法表示,此时如果需要计算所得出数字类型的结果需要使用BigDecimal类型。
但是使用BigDecimal计算时又发现了这样一个情况:
BigDecimal bigDecimalDouble = new BigDecimal(100000000000000.0d).add(new BigDecimal(0.9d));
System.out.println(bigDecimalDouble.toString());
结果:
100000000000000.90000000000000002220446049250313080847263336181640625
为了最大化的消除精度影响,必须使用String参数构造BigDecimal 即:
BigDecimal bigDecimalString = new BigDecimal("100000000000000.0").add(new BigDecimal("0.9"));
System.out.println(bigDecimalString.toString());
结果:
100000000000000.9
特别注意!!!
BigDecimal 比较大小不可以直接使用<>=,也不可以使用equlse进行比较
需使用compareTo函数进行比较大小运算
boolean i = new BigDecimal("1.0").compareTo(new BigDecimal("1.00")) == 0;
boolean i1 = new BigDecimal("1.0").equals((new BigDecimal("1.00")));
boolean i2 = new BigDecimal("1.0") == (new BigDecimal("1.00"));
System.out.println(i + "," + i1 + "," + i2);
结果:
true,false,false
特别注意!!!
Integer使用==判断相等会出现问题
public static void main(String[] args) {
Integer i1 = 127;
Integer i2 = 127;
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i1.equals(i2));
System.out.println(i1 == i2);
System.out.println(i1.compareTo(i2));
System.out.println(i3.equals(i4));
System.out.println(i3 == i4);
System.out.println(i3.compareTo(i4));
}
输出
true
true
0
true
false
0
原理说明 ,在Integer<127时, JVM会进行内存优化, 使用常量池中的数据 ,因此 i1 == i2, Integer>.127时 ,会new出一空间进行数据存放 ,因此直接==判断是他的地址, i3 != i4
版权声明:本文为sj18871700315原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。