我想使用在此实例化的确切值来检索bigDecimal的值
BigDecimal balance = new BigDecimal(2300000870000000000067.7797);
我目前使用余额检索的值为2300000869999999975424。 您能告诉我如何将其检索为2300000870000000000067.7797吗?
答案 0 :(得分:3)
您已使用java.math.BigDecimal.BigDecimal(double val)
构造函数。
来自 JavaDoc :
java.math.BigDecimal.BigDecimal(double val)
Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value. The scale of the returned BigDecimal is the smallest value such that (10scale × val) is an integer.
Notes:
1. The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
2. The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.
3. When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method.
此处第一点表明:
此构造函数的结果可能有些不可预测。可能假定用Java编写新的BigDecimal(0.1)会创建一个BigDecimal,它精确地等于0.1(未缩放的值1,带有一个1),但实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法精确表示为双精度(或就此而言,表示为任何有限长度的二进制分数)。因此,尽管出现,但是传递给构造函数的值并不完全等于0.1。
第二点建议使用带有字符串参数的构造函数以获得确切的值。
这是价值差异的原因。
答案 1 :(得分:0)
java文档本身建议有关BigDecimal(Double val)
:
此构造函数的结果可能无法预测。
您应该改用以下内容:
BigDecimal balance = new BigDecimal("2300000870000000000067.7797");
答案 2 :(得分:0)
您正在尝试使用不能容纳最大精度为15位小数的双精度数的立即数-可能是为什么您想首先使用BigDecimal的原因。因此,在初始化BigDecimal之前,您的数字将被转换为最精确的两倍。然后,BigDecimal构造函数通过将已经弄乱的double弄乱来加重错误。
您必须将数字表示为字符串才能获得精度。
double x = 2300000870000000000067.7797d;
System.out.println("double:"+x);
BigDecimal balance = new BigDecimal(2300000870000000000067.7797);
System.out.println("balance:"+balance);
BigDecimal stringbased = new BigDecimal("2300000870000000000067.7797");
System.out.println("stringbased:"+stringbased);
打印
double:2.30000087E21
balance:2300000869999999975424
stringbased:2300000870000000000067.7797