在Java中,我想获取一个double值并将其转换为BigDecimal
并将其String值打印到一定的精度。
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
转换的原因有时候,double值会包含很多小数位(即-.000012
),将double转换为String时会生成科学记数法{ {1}}。我想以非科学记数法存储String值。
我希望BigDecimal总是有两个精度单位:“47.48”。 BigDecimal可以限制转换为字符串的精度吗?
答案 0 :(得分:87)
这种行为的原因是打印的字符串是确切的值 - 可能不是您所期望的,但这是存储在内存中的实际值 - 它只是浮点表示的限制。
根据javadoc,如果不考虑此限制,BigDecimal(double val)构造函数行为可能会出乎意料:
这个构造函数的结果可能有些不可预测。一 可能会假设在Java中编写新的BigDecimal(0.1)会创建一个 BigDecimal正好等于0.1(未缩放的值为1,带有 比例为1),但它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能完全表示为double(或者为此) 重要的是,作为任何有限长度的二进制分数)。因此,价值 传入构造函数的不完全等于 0.1,尽管有外表。
所以在你的情况下,而不是使用
double val = 77.48;
new BigDecimal(val);
使用
BigDecimal.valueOf(val);
BigDecimal.valueOf返回的值等于调用Double.toString(double)
所产生的值。
答案 1 :(得分:45)
答案 2 :(得分:15)
您想尝试String.format("%f", d)
,它会以十进制表示法打印您的双倍。不要使用BigDecimal
。
关于精确度问题:您首先在47.48
中存储double c
,然后从BigDecimal
创建新的double
。精度的损失在于分配给c
。你可以做到
BigDecimal b = new BigDecimal("47.48")
以避免失去任何精确度。
答案 3 :(得分:5)
它打印出double
的实际精确值。
Double.toString()
转换为double
s的 String
不打印输入的确切十进制值 - 如果x
是你的双倍值,它打印出的数字恰好足以使x
与其打印的值最接近double
。
关键在于与47.48完全没有double
。双倍存储值为二进制分数,而不是小数,因此它不能存储精确的十进制值。 (这就是BigDecimal
的用途!)
答案 4 :(得分:5)
为什么不:
b = b.setScale(2, RoundingMode.HALF_UP);
答案 5 :(得分:3)
String.format语法帮助我们将双精度数和BigDecimals转换为任何精度的字符串。
这个java代码:
double dennis = 0.00000008880000d;
System.out.println(dennis);
System.out.println(String.format("%.7f", dennis));
System.out.println(String.format("%.9f", new BigDecimal(dennis)));
System.out.println(String.format("%.19f", new BigDecimal(dennis)));
打印:
8.88E-8
0.0000001
0.000000089
0.0000000888000000000
答案 6 :(得分:2)
BigDecimal b = new BigDecimal(c).setScale(2,BigDecimal.ROUND_HALF_UP);
答案 7 :(得分:0)
在Java 9中,不推荐使用以下内容:
BigDecimal.valueOf(d).
<击> setScale 击> (2, BigDecimal.
<击> ROUND_HALF_UP 撞击> );
改为使用:
BigDecimal.valueOf(d).setScale(2, RoundingMode.HALF_UP);
示例:
double d = 47.48111;
System.out.println(BigDecimal.valueOf(d)); //Prints: 47.48111
BigDecimal bigDecimal = BigDecimal.valueOf(d).setScale(2, RoundingMode.HALF_UP);
System.out.println(bigDecimal); //Prints: 47.48