parseFloat()与parseDouble()

时间:2014-04-09 17:50:10

标签: java string floating-point double

我正在尝试下面的代码将字符串转换为float和double但得到不同的结果。

代码:

 System.out.println(Float.parseFloat("120059389"));
 System.out.println(Double.parseDouble("120059389"));

输出:

1.20059392E8
1.20059389E8

有人可以解释一下为什么我在float和double中解析字符串会得到不同的结果吗? float和double的范围是什么?

3 个答案:

答案 0 :(得分:10)

这是因为你试图通过给它提供比它能处理的精度更多的数字来解析float"ulp" (unit in last place) of a float那个大8.0,但"ulp" for a double那个大的仍然相当小。也就是说,在那个幅度上,最接近的可能float值相差8,但最接近double值的精度更高,相差更远。

System.out.println(Math.ulp(120059389f));
System.out.println(Math.ulp(120059389d));

打印:

8.0
1.4901161193847656E-8

因此Float解析器必须使用与float的真实值最接近的120059389,恰好是1.20059392E8

答案 1 :(得分:6)

不同之处在于DoubleFloat以不同方式存储数字。

使用单精度和双精度,允许Double给予 Double Float可以处理的精度。

所以简单的答案是,由于FloatDouble相比有限的内存信息在Float范围之外的数字转换时会丢失。

  • Float:32位数字
  • Double:64位数字

因此,在转换过程中,某些信息在转换为Float时会丢失,因为它会被截断。

...一般

Float将数字存储为符号(-/+)的1位,指数的8位,以及分数的23位。

Double将数字存储为符号(-/+)的1位,指数的8位,以及分数的53位。

当你转换你的号码时,120059389 = 111001001111111010111111101b有27位信息,Double的53位允许值可以覆盖这些信息,但不能由Float&#覆盖39; s 23位允许,数据在最不重要的一端被截断。

转换将使用23位1.20059392 = 111001001111111011000000000b将数字四舍五入到最接近的可表示数字,指数将处理剩余的扩展。

答案 2 :(得分:1)

早期的链接和答案提供了很好的技术答案。 ' laymans'答案是浮点数是32位,双数是64位。其中一些位用于数字,一些用于指数。您在代码中输入的数字只有32位' float'的数字太多。 64位'双'有更多的位,更大的数字可以更精确。

当达到64位双精度且需要128位精度时,相同的概念适用于更大的数字。