将双精度转换为大十进制并设置大十进制精度

2022-08-31 10:40:52

在Java中,我想取一个双精度值并将其转换为a,并将其String值打印出来到一定的精度。BigDecimal

import java.math.BigDecimal;
public class Main {
    public static void main(String[] args) {
        double d=-.00012;
        System.out.println(d+""); //This prints -1.2E-4

        double c=47.48000;
        BigDecimal b = new BigDecimal(c);
        System.out.println(b.toString()); 
        //This prints 47.47999999999999687361196265555918216705322265625 
    }
}

它打印了这个巨大的东西:

47.47999999999999687361196265555918216705322265625

而不是

47.48

我进行转换的原因是有时双精度值将包含很多小数位(即),并且将双精度值转换为字符串时会产生科学记数法 。我想以非科学记数法存储字符串值。BigDecimal-.000012-1.2E-4

我希望BigDecimal始终具有两个这样的精度单位:“47.48”。BigDecimal可以限制转换为字符串的精度吗?


答案 1

这种行为的原因是打印的字符串是确切的值 - 可能不是你期望的,但这是存储在内存中的实际值 - 它只是浮点表示的限制。

根据javadoc,如果你不考虑这个限制,BigDecimal(double val)构造函数的行为可能是意外的:

此构造函数的结果可能有些不可预测。有人可能会假设在Java中编写新的BigDecimal(0.1)会创建一个正好等于0.1的BigDecimal(一个未缩放的值1,小数位数为1),但它实际上等于0.100000000000000000000055511151231257827021181583404541015625。这是因为 0.1 不能完全表示为双精度值(或者,就此而言,不能表示为任何有限长度的二进制分数)。因此,尽管外观不同,传递给构造函数的值并不完全等于 0.1。

所以在你的情况下,而不是使用

double val = 77.48;
new BigDecimal(val);

BigDecimal.valueOf(val);

由 BigDecimal.valueOf 返回的值等于调用 所得到的值。Double.toString(double)


答案 2

如果您使用其他 MathContext,它将打印 47.48000:

BigDecimal b = new BigDecimal(d, MathContext.DECIMAL64);

只需选择您需要的上下文即可。


推荐