你面临的问题是0.1被表示为稍微更高的数字,例如:
System.out.println(new BigDecimal(0.1));
打印
0.1000000000000000055511151231257827021181583404541015625
Double.toString() 方法会考虑到此表示误差,因此您看不到它。
同样地,0.3被表示为比其实际值稍低的值。
0.299999999999999988897769753748434595763683319091796875
如果你将0.1的表示值乘以3,则无法得到0.3的表示值,而是会得到稍微高一点的值。
0.3000000000000000166533453693773481063544750213623046875
这不仅是表示错误,还包括操作引起的舍入误差。这种误差超过了Double.toString()可以纠正的范围,因此您会看到舍入误差。
故事的寓意是,如果您使用float或double也请适当四舍五入解决问题。
double d = 0.1 + 0.1 + 0.1;
System.out.println(d);
double d2 = (long)(d * 1e6 + 0.5) / 1e6; // round to 6 decimal places.
System.out.println(d2);
打印
0.30000000000000004
0.3
BigDecimal
,实际上你在做和添加双精度浮点数一模一样的事情。doubleValue()
返回的是一个双精度浮点数。请参考BigDecimal
的 Javadoc 了解如何进行加减等操作。 - Brian Roachdouble
计算问题,请查看《计算机科学家应该了解的浮点数算术知识》。Java通过提供输出格式选项来解决这个问题。 - Andrew ThompsondoubleValue()
???我以为你想要一个十进制类型。 - Kerrek SB