BigDecimal 到 Double 以添加到 JSON 对象

BigDecimal to Double in order to add to JSON Object

我们如何在不损失 Kotlin 精度的情况下将 BigDecimal 转换为 Double?。我需要将其放入 JSON 响应中。

我正在使用 Vert.x 和 JsonObject。我试过将比例为 2 的 BigDecimal 转换为 toDouble 的 Double。在内部它使用 Jackson 作为对象映射器

示例:

目前:
BigDecimal("0.000") -> 响应:{ amount: 0.0 }

我需要的:
BigDecimal("0.000") -> 响应:{ amount: 0.000 }

恐怕您不能将 BigDecimal 转换为 Double 而不会丢失精度,原因如下:

  • BigDecimal 的可能值比 Double 多得多,因此转换必然有损。

双精度数是 64 位的,因此不同的值不能超过 2⁶⁴,而 BigDecimals 实际上是无限的。

  • BigDecimals 存储小数,而 Doubles 存储二进制小数。两者之间几乎没有重叠,因此在大多数情况下,转换需要对值进行舍入。

两者都可以精确存储整数(不超过某个值),都可以精确存储小数,例如 0.5。但是几乎所有的小数都不能精确地表示为二进制小数,因此例如没有 Double 正好保持 0.1。 (1/10 是二进制的无限循环分数 - 0.0001100110011 ... - 因此没有有限的二进制分数可以准确表示它。)

这意味着在 Kotlin(和大多数其他编程语言)中,诸如 0.1 之类的数字文字会转换为最接近的双精度数,大约为 0.1000000000000000005551115…。实际上,这通常对您是隐藏的,因为当您打印出 Double 时,格式化例程会将其四舍五入,并且在许多情况下会返回原始数字。但并非总是如此,例如:

>>> println(0.1 + 0.1 + 0.1)
0.30000000000000004

(所有这些都在其他问题中讨论,最值得注意的是 here。)

  • 与 BigDecimals 不同,Double 没有精度,因此无论如何它们都无法做出您想要的区分。

例如,1.0 和 1.000000 都由完全相同的 Double 值表示:

>>> println(1.000000)
1.0

我不知道 Vert.x,但如果您真的需要 Double,我会很惊讶。您是否尝试过直接使用 BigDecimal?

或者,如果这不起作用,您是否尝试过将其转换为字符串,这将保留您想要的任何格式?