parseFloat()与parseDouble()

vik*_*for 4 java string floating-point double

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

码:

 System.out.println(Float.parseFloat("120059389"));
 System.out.println(Double.parseDouble("120059389"));
Run Code Online (Sandbox Code Playgroud)

输出:

1.20059392E8
1.20059389E8
Run Code Online (Sandbox Code Playgroud)

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

rge*_*man 10

这是因为你试图float通过给它提供比它能处理的精度更多的数字来解析a .那个大的"ulp"(最后一个单位)float8.0,但是那个大的"ulp"double仍然相当小.也就是说,在那个幅度上,最接近的可能float值相差8,但是double具有更高精度的最接近的值差异远小得多.

System.out.println(Math.ulp(120059389f));
System.out.println(Math.ulp(120059389d));
Run Code Online (Sandbox Code Playgroud)

这打印:

8.0
1.4901161193847656E-8
Run Code Online (Sandbox Code Playgroud)

所以Float解析器必须使用最接近float于真实价值120059389,这恰好是1.20059392E8.


Far*_*Joe 6

不同之处在于Double,Float存储数字的方式不同.

有单,双精度,从而Double精度的量Float能处理.

所以简单的答案就是因为FloatDouble信息相比有限的内存在转出数量超出范围时Float就会丢失.

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

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

通常...

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

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

当你转换你的数字120059389 = 111001001111111010111111101b有27位的信息,这可以用Double53位的容量覆盖,但不能用Float23位的容差覆盖,数据在最不重要的一端被截断.

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