欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java小数计算

程序员文章站 2022-07-15 09:35:34
...

说到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