【发布时间】:2020-12-07 09:28:54
【问题描述】:
以下代码打印12113411122222,545000:
Double value = 12113411122222.545421d;
System.out.println(String.format("%f", value));
如何确定变量 value 被分配给打印的确切值 - 12113411122222.545421?
更新:我应该在一开始就这么说——我知道需要精确时需要使用BigDecimal。但是,我正在使用一个库来读取某种类型的文件,结果是我从该文件中获得了一堆属性。其中一个属性是从第 3 方库作为双重传递给我的。之后,我将属性值发送到数据库,导致属性值被保存为1.2113411122222545E13,因为值被转换为String。所以现在我正在寻找一个解决方案如何“丢失”指数部分并做出假设:如果Double.MAX_VALUE 是1.7976931348623157E308 那么这意味着我可能会得到带有很多十进制数字的属性值,例如12113411122222.545421121212212d,以及如何做我将 Double 转换为 String 而不会“丢失”任何数字。我怀疑这是Double 精度的问题,但这是违反直觉的,因为Double.MAX_VALUE 是1.7976931348623157E308。我想更好地了解 Java 的内部工作和计算机系统中的一般数字是理解这个问题的必要条件。
【问题讨论】:
-
改用
BigDecimal。doubles 本质上是不精确的。 -
64bit double 没有这个范围,它们基本上可以使用最多 15 位数字。如果您想获得如此高的精度,则需要另一种数据类型。
-
你不能。
double没有足够的精度来表示您分配的数字。 -
Java Double 是一种精度有限的浮点类型。如果您有太多有效数字,您将丢失一些信息,并且 Double 开始四舍五入。使用 BigDecimal 以获得更好的精度。或者,如果您只是传输值而不进行数学运算,请考虑使用 String 而不是 Double。
-
你无法避免这种情况,如果你依赖它被精确表示,这确实会成为错误的来源。例如,这样的浮点文字被标记为问题in Google's error prone。
标签: java double decimal precision