我有一个Double我就是这样创建的:
Double d = Double.parseDouble( "27.86753" ); // All the digits of this double value are 27.867530822753906
这个特殊的double也可以用float表示,所以Java会删除其余的数字。我如何强制Java给我这个值的真正双重表示(所有数字)?
答案 0 :(得分:5)
哦,伙计,有趣。您想要准确了解double
我认为new BigDecimal(double).toString()
会给你所有不正确的数字,因为BigDecimal
代表一个具有精确指定精度的数字。
让我尝试解释一下:Double.toString
返回最不精确的String
,以便Double.parseDouble
返回完全相同的double
- 只是< / em>足够的数字来“唯一地标识”确切的IEEE 754值,尽管实际值可能比打印的数字更多。仅仅因为Double.toString
没有给出你想象的数字,并不意味着实际的 IEEE 754双精度值被舍入到那么多位数。 new BigDecimal(double).toString
将返回存储的确切IEEE-754值。
更新:
正在发生的事情是,当它打印出27.86753
时,它实际上内部是更多精确值,而不是您引用的数字作为正确答案27.867530822753906
。这只是因为toString
旨在打印出尽可能多的内容,以确保Double.parseDouble(Double.toString(value))
是无操作。
我运行了以下代码:
public static void main(String[] args) {
double dWithFloat = Double.parseDouble(Double.toString(Float.parseFloat("27.86753")));
double dJustParsed = Double.parseDouble("27.86753");
System.out.println(dWithFloat);
System.out.println(dJustParsed);
BigDecimal bigFromFloat = new BigDecimal(dWithFloat);
BigDecimal bigJustParsed = new BigDecimal(dJustParsed);
System.out.println(bigFromFloat);
// prints the exact value from the double,
// doesn't round or truncate like Double.toString
System.out.println(bigJustParsed);
}
并打印出来
27.867530822753906 // Double.toString(Double.parseDouble(Double.toString(Float.parseFloat("27.86753"))));
27.86753 // Double.toString(Double.parseDouble("27.86753")) is indeed a no-op
27.86753082275390625 // This is the _actual_ value from D.parseD(D.toString(F.parseF("27.86753")))
27.867529999999998580051396857015788555145263671875 // This is the actual value from D.parseD("27.86753")
事实上,第二个值明显接近27.86753,差距为0.0000008。
答案 1 :(得分:1)
您可能需要考虑使用 java.math.BigDecimal
,您可以通过明确的方法来控制比例和舍入规则。 Double不能这样做。
答案 2 :(得分:0)
丑陋但它有效:
Double d = Double.parseDouble( Double.toString( Float.parseFloat( "27.86753" ) ) ); // Sets the value of the Double to 27.867530822753906