我的应用程序产生的双精度浮点数,使用Double.toString()方法会产生"-3.1999999999999953",但我期望它应该是"-3.2"。
实际上,这些双精度浮点数是从JScience的Amount#getEstimatedValue()
中获取的。
我不想为精度设置任意数字,因为我不知道有多少位数字是有效的,但我也不想生成以"99999999.*"结尾的数字。
如何避免这个问题将双精度浮点数转换为字符串?
我的应用程序产生的双精度浮点数,使用Double.toString()方法会产生"-3.1999999999999953",但我期望它应该是"-3.2"。
实际上,这些双精度浮点数是从JScience的Amount#getEstimatedValue()
中获取的。
我不想为精度设置任意数字,因为我不知道有多少位数字是有效的,但我也不想生成以"99999999.*"结尾的数字。
如何避免这个问题将双精度浮点数转换为字符串?
推荐解决方案
BigDecimal.valueOf (hisDouble).toPlainString ()
在本文的最后一节中提供的黑客技巧是我尝试解决问题时首先想到的。
然后,一个朋友问我正在做什么,并表示OP最好使用BigDecimal
,于是我陷入了沮丧的状态。
但我将在本文中保留这个黑客技巧,以便全世界都能看到我有时会变得多么愚蠢。
在打印时可以使用System.out.format
。
以下代码片段将会将yourDecimal
的值舍入到小数点后一位,然后打印该值。
Double yourDouble = -3.1999999999999953;
System.out.format ("%.1f", yourDouble);
输出
-3.2
public static String fixDecimal (Double d) {
String str = "" + d;
int nDot = str.indexOf ('.');
if (nDot == -1)
return str;
for (int i = nDot, j=0, last ='?'; i < str.length (); ++i) {
j = str.charAt (i) == last ? j+1 : 0;
if (j > 3)
return String.format ("%."+(i-nDot-j-1)+"f", d);
last = str.charAt (i);
}
return str;
}
...
Double[] testcases = {
3.19999999999953,
3.145963219488888,
10.4511111112,
100000.0
};
for (int i =0; i < testcases.length; ++i)
System.out.println (
fixDecimal (testcases[i]) + "\n"
);
输出
3.2
3.1459632195
10.45
100000.0
你可以尝试
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/DecimalFormat.html
稍微有点“笨重”,但应该可以解决问题。一些使用示例在以下链接中: