我的实验表明,边界为24,该边界由-Double.MIN_NORMAL
达到,其结果为
-2.2250738585072014E-308
......但我无法证明它,也不能得出任何结论,说明为什么没有其他值能够超过-MIN_NORMAL
。
我的实验表明,边界为24,该边界由-Double.MIN_NORMAL
达到,其结果为
-2.2250738585072014E-308
......但我无法证明它,也不能得出任何结论,说明为什么没有其他值能够超过-MIN_NORMAL
。
这是一个64位的IEEE-754浮点数。
52位尾数可以存储的最大十进制数是17(参见第4页:ceil( 1 + N Log10(2) )
),所以带有小数点和负号的数值最长为19个字符。
偏移量为1023,因此最小的基数指数是2^-1022,约为10^-308,所以最长的指数为5个字符,并带有'E'和负号。
19 + 5 == 24
System.out.println(Long.toString((1L << 52) - 1).length());
返回的是16,或者我翻译错了吗? - Louis Wasserman26似乎是一个上限,具体如下。
根据GrepCode的FloatingDecimal.getChars
版本,OpenJDK7 断言值nDigits
最多为19。从代码来看,nDigits
似乎是指尾数(而非小数点)的数字,在上面的示例中,是22250738585072014
。然后,其他字符包括:
-
符号.
小数点E
-
符号这样就有19 + 7 = 26个字符。
(对于更严格的界限的论证仍然受欢迎。)
我认为这个界限是正确的。javadoc说:
一个必须打印多少位小数部分的
m
或a
? 必须至少有一位数字来表示小数部分,除此之外还需要尽可能多的数字,但只需要足以唯一地区分类型 double 的相邻值。
double
有一个隐含的整数部分 (1) 和 52 个尾数位。因此,如果由 double
表示的基数2指数为0,使得 x
是范围在 [1,2) 的 double
,那么下一个更高的相邻 double
是 x
+ 2-52。2-52 大约是 2.2204 * 10-16。这表明区分一个值与下一个相邻值所需的小数位数为16,即1旁边的双倍数将表示为 1.0000000000000002
(15个零)。由于这与您的实验中的小数位数匹配,因此很可能确实是永远需要的最大数量。当然,这不是严格的证明;这需要更多的工作。
FloatingDecimal
很可能可以表示比double
更大的数字,因此很容易相信 26 大于double
所需的大小。但是,正如我所说,这是一个上限。) - Hot Licks-Extremadamentemierdaenorme
,共27个字符。 - Glenn Lane