为什么BigDecimal在Java中返回我的大双精度的近似值?

我想舍入我的大双精度数,所以我决定做的第一件事是按以下方式将其转换为 BigDecimal。

    BigDecimal amount = BigDecimal
        .valueOf(getAmount())
        .setScale(2, RoundingMode.HALF_UP);
    System.out.println(amount);

在我的示例中,getAmount()返回123456789123123424113.31.

因此,我希望我的代码片段打印出完全相同的值。

相反,我得到以下值:

123456789123123430000.00

有人可以解释为什么 BigDecimal 返回我的 double 的近似值吗?

回答

在我的示例中,getAmount()返回123456789123123424113.31.

不,不是的。那不是 adouble可以准确表示的值。

您可以使用以下代码轻松验证:

double d = 123456789123123424113.31d;
System.out.println(d);
double d = 123456789123123424113.31d;
System.out.println(d);

哪些输出

该值具有最少的位数,可以唯一地将其与任何其他double值区分开来。这意味着double. 你已经失去了精度之前的值转换为BigDecimal

虽然诸如long和 之类的整数数据类型int可以精确地表示其范围内的每个(整数)值,但对于浮点数却不能这样说:它们可以表示的值范围很广,但代价是不能够表示范围内的每个可能的值。实际上,浮点数可以表示的位数是有限的(大约 16 位十进制数字double和大约 7 位十进制数字)float)。其他一切都将被切断。

如果您需要任意精度,那么类似的东西BigDecimal会有所帮助:它将根据需要分配尽可能多的内存来保存所有数字(或根据您的规范进行舍入,如果需要),使其更复杂但也更强大。

BigDecimal bd = new BigDecimal("123456789123123424113.31");
System.out.println(bd);

将打印

1.2345678912312343E20

确保不要BigDecimaldouble值初始化,因为即使那样你也只能得到截止值。

  • @p4t: use `BigDecimal` all throughout your calculation and never convert anything to a `double` (not even for intermediate results). Also make sure those `BigDecimal` are not **initialized** from `double` values (use the `String` constructor if you need decimal points).

以上是为什么BigDecimal在Java中返回我的大双精度的近似值?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>