正如许多地方所解释的那样(例如为什么十进制数不能精确地用二进制表示?),并不是所有的十进制分数都可以表示为浮点值(例如存储在Java中的float
中)。
给出的典型例子是"0.2"。根据这个漂亮的IEEE 754转换器,最接近0.2的float
大约是0.20000000298023224,所以将"0.2"解析为float
应该会得到这个结果。
然而,我注意到Java似乎能够做不可能的事情:
String number="0.2";
float f = Float.parseFloat(number);
System.out.println("Result of roundtrip String -> float -> String: "+f);
打印:
返回String -> float -> String: 0.2
在IDeone.com上测试
Java如何知道我想要(四舍五入)输出"0.2",而不是精确输出"0.20000000298023224"如上所述?
Float.toString()
的Javadocs试图解释这一点:
m或a的小数部分必须打印多少位数字?必须至少有一个数字来表示小数部分,并且除此之外,需要多少位数,但只有多少位数唯一区分参数值与类型的相邻值浮动。
不幸的是,这更让我困惑。为什么"打印尽可能多的数字以唯一区分参数值"允许Java打印"0.2"?
理想情况下,答案也会解释为什么选择这个打印算法。它是使(一些)往返工作,如在这个例子中?还有其他动机吗?
输出的四舍五入不是由于某些打印算法。这是因为float
的大小。
String fs = "0.2";
double f = Float.parseFloat(fs);
System.out.println(f);
你:
0.20000000298023224
在Ideone.com上测试
这清楚地表明字符串"0.2"被解析为0.20000000298023224,但float数据类型无法保存它,并将其四舍五入到0.2。double
数据类型能够保存此数据,因此,当将其解析为float,但将其存储在双精度中时,您将得到预期的输出。
我猜0.2属于"Value Set Conversion"