java - 在控制台中输出时的float精度

时间:2014-02-08 09:25:20

标签: java floating-point

float x = 0.98123452f;
System.out.println(x); //it prints out 0.9812345

float x = 0.98123453f;
System.out.println(x); //it prints out 0.98123455

我不知道为什么第二个输出是0.98123455而不是0.9812345。浮点数的精度是不是7位十进制数?

5 个答案:

答案 0 :(得分:1)

要查看浮动的确切值,可以使用BigDecimal:

float x = 0.98123452f;
System.out.println(new BigDecimal(x));

输出:0.981234490871429443359375

从技术上讲,这个浮动:

float x = 0.981234490871429443359375f;
System.out.println(new BigDecimal(x)); //prints 0.981234490871429443359375

有24位精度(显然是挑选的)...

忘记上面的内容:BigDecimal只有一个双构造函数,所以有一个转换为double,上面的逻辑是有缺陷的。

底线:并非所有数字都可以表示为浮点数,一个浮点数与下一个浮点数之间的差距会根据数字的大小而变化。

答案 1 :(得分:1)

的IEEE 754浮点表示
0.98123453 

是32位(符号,exp,尾数):

0 01111110 11110110011001000110000

是:

0.9812345504760742

以双精度,并转回浮点十进制表示:

 0.98123455

分配给单个精度(浮点数)的位数为32,双精度为64位。请注意,经常建议的BigDecimal会将您的号码存储为字符串,而不是IEEE754格式。当需要对数字进行操作时会进行转换,而且它会更好精确,它非常慢。

编辑。为了澄清它打印0.98123455的原因,我们需要观察它是数字0.98123453的最接近的单精度表示:

00111111011110110011001000101111 = 0.9812345  (sp) = 0.9812344908714294 (dp)
00111111011110110011001000110000 = 0.98123455 (sp) = 0.9812345504760742 (dp)
00111111011110110011001000110001 = 0.9812346  (sp) = 0.981234610080719  (dp)

sp =单精度,dp =双精度

列表是针对数字的[-1,+ 1]二进制范围,您可以看到0.98123453最接近尾数的10000后缀,而{{1} }最接近0.98123452后缀。

答案 2 :(得分:1)

  

浮点数的精度是不是7位十进制数?

没有。它是23个二进制数字。因此,可以用23位表示的最小小数位数为6.这不仅仅是“保证”,如其他答案中所述,它是由log10(2 ^ 23)= 6.92369引起的数学重言式。

答案 3 :(得分:1)

Java中浮点的默认输出格式是打印足够的数字,以便转换回浮点类型产生原始值。

您的代码中详细说明了:

  • 源文本0.98123452f将转换为float值0.981234490871429443359375。
  • 打印为“0.9812345”,因为这只是足够的数字。最接近float的值为0.9812345是0.981234490871429443359375。但是,将“0.981234”转换为float将产生0.981234014034271240234375,因此需要“5”。
  • 源文本0.98123453f将转换为float值0.98123455047607421875。
  • 打印为“0.98123455”,因为这只是个数字。

这样做的一个有趣结果是,如果您为float对象分配double值然后打印double值,它通常会显示比打印{更多的数字} {1}}值,即使值完全相同。由于float格式比double格式更精细(更精确),因此float打印的值(例如0.9812345)与实际值之间可能存在多个double值值(0.981234490871429443359375)。因此,需要更多数字来区分该值。

答案 4 :(得分:0)

不,float只有十位十进制精度。