Java,Float.parseFloat(),System.out.printf()不一致

时间:2013-09-09 15:51:00

标签: java

考虑Java中的以下代码:

String input = "33.3";
float num = Float.parseFloat(input);  
System.out.printf("num: %f\n",num);      

为什么输出上面的代码

num: 33.299999

不应该是

num: 33.300000

如果有人能向我解释,我真的很感激。

4 个答案:

答案 0 :(得分:7)

您是浮点错误的受害者。在基数2中,33.3在技术上是重复的二进制(类似于重复的十进制),就像m/n mn为整数而写gcd(m,n)=1 n的素因子不是2的素因子的子集。这也意味着它不能写成有限数量的项m*(2^n)的总和mn是整数。

基数为10的7/6也会出现类似的例子。

   _
1.16

变为

1.16666667

然后按字面读取,并且不等于7/6。

答案 1 :(得分:3)

如果可以避免,请不要使用float。这里的问题是%f在没有那种精度的情况下将其视为双精度

String input = "33.3";
double num = Double.parseDouble(input);
System.out.printf("num: %f\n",num);

打印

33.300000

这是因为33.3f!= 33.3,float精度较低。要查看实际值,您可以使用BigDecimal,它精确地覆盖实际值。

System.out.println("33.3f = " + new BigDecimal(33.3f));
System.out.println("33.3 = " + new BigDecimal(33.3));

打印

33.3f = 33.299999237060546875
33.3 = 33.2999999999999971578290569595992565155029296875

正如您所看到的,两种情况下所表示的真实值都略微过小。在%f如何显示6个小数位的情况下,即使浮点数不准确到总共8个小数位。 double精确到15-16位小数,因此除非值更大,否则您不会看到错误。例如一万亿或更多。

答案 2 :(得分:1)

问题在于浮点数具有有限的精度。

答案 3 :(得分:1)

32位浮点数包含足够的精度,大约精确到7位小数。 33.29999是小数点后7位。 将“输入”更改为3.3 - 您应该看到3.300000 将“输入”更改为333.3 - 您将看到如下内容:333.299988 使用64位浮点数可以提供更高的精度(15-17位小数)。