0

考虑以下 Java 代码:

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

为什么上面代码的输出

num: 33.299999 ?

难道不应该

num: 33.300000 ?

如果有人可以向我解释这一点,我将不胜感激。

4

4 回答 4

7

你是浮点错误的受害者。在基数 2 中,33.3在技术上是重复的二进制(类似于重复的小数),当写成m/n和是整数和m时, 的素因数不是 2 的素因数的子集。这也意味着它不能写作为有限数量的项之和,其中和是整数。ngcd(m,n)=1nm*(2^n)mn

类似的例子发生7/6在以 10 为底的情况下。

   _
1.16

变成

1.16666667

然后按字面意思阅读,不等于 7/6。

于 2013-09-09T15:53:09.613 回答
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 asfloat的精度较低。要查看实际值,您可以使用精确覆盖实际值的 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 位,因此除非值更大,否则您不会看到错误。例如一万亿或更多。

于 2013-09-09T15:54:50.307 回答
1

32 位浮点数包含大约 7 个小数位精度的足够精度。33.29999 是小数点后 7 位。将“输入”更改为 3.3——你应该看到 3.300000 将“输入”更改为 333.3——你会看到类似:333.299988 使用 64 位浮点数会给你更高的精度(15-17 位小数)。

于 2013-09-09T16:00:31.207 回答
1

问题很简单,浮点数的精度是有限的。

于 2013-09-09T15:52:55.290 回答