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"(最后一个单位)float是8.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.
不同之处在于Double,Float存储数字的方式不同.
有单,双精度,从而Double给双精度的量Float能处理.
所以简单的答案就是因为Float与Double信息相比有限的内存在转出数量超出范围时Float就会丢失.
Float :32位数字Double :64位数字因此,在转换过程中,某些信息在转换为时会丢失,Float因为它会被截断.
通常...
Float将数字存储为符号(-/+)的1位,指数的8位,以及分数的23位.
Double将数字存储为符号(-/+)的1位,指数的8位,以及分数的53位.
当你转换你的数字120059389 = 111001001111111010111111101b有27位的信息,这可以用Double53位的容量覆盖,但不能用Float23位的容差覆盖,数据在最不重要的一端被截断.
转换将使用23位将数字四舍五入到最接近的可表示数字1.20059392 = 111001001111111011000000000b,指数将处理剩余的扩展.