我正在尝试下面的代码将字符串转换为浮点型和双精度,但得到了不同的结果。
代码:
System.out.println(Float.parseFloat("120059389"));
System.out.println(Double.parseDouble("120059389"));输出:
1.20059392E8
1.20059389E8有没有人能解释一下为什么我在分析float和double中的字符串时得到了不同的结果?浮点数和双精度数的范围是多少?
发布于 2014-04-10 01:53:07
这是因为您试图通过为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解析器必须使用最接近120059389真实值的float,恰好是1.20059392E8。
发布于 2014-04-10 01:53:02
不同之处在于Double和Float存储数字的方式不同。
具有单精度和双精度,允许Double提供Float可以处理的两倍精度。
因此,简单的答案是,由于与Double相比,Float的内存有限,因此在将数字转换到Float可以处理的范围之外时,信息就会丢失。
Float:32位NumbersDouble:64位数字因此,在转换过程中,一些信息在转换为Float时会丢失,因为它被截断了。
一般来说..。
Float将数字存储为符号(-/+)的1位、指数的8位和小数的23位。
Double将数字存储为符号(-/+)的1位、指数的8位和小数的53位。
当您转换您的号码时,120059389 = 111001001111111010111111101b有27位的信息,这些信息可以被Double的53位余量覆盖,但不能被Float的23位余量覆盖,并且数据在最低有效端被截断。
转换将使用23位1.20059392 = 111001001111111011000000000b将数字舍入到最接近的可表示数字,指数将处理其余的扩展。
发布于 2014-04-10 02:00:58
前面的链接和答案提供了很好的技术答案。“外行”的答案是,浮点数是32位,双精度数是64位。其中一些位用于数字,另一些位用于指数。你在代码中输入的数字对于32位的“浮点数”来说太多了。64位的“双精度”有更多的位数,更大的数字可以更精确。
当您达到64位双精度的限制并需要128位精度时,同样的概念也适用于更大的数字。
https://stackoverflow.com/questions/22970240
复制相似问题