为什么Double.MIN_VALUE不是负数?

198

有人能解释一下为什么Double.MIN_VALUE实际上不是Double可以取到的最小值吗?它是一个正数,而Double当然可以是负数。

我明白它为什么是一个有用的数字,但与Integer.MIN_VALUE相比,它似乎是一个非常不直观的名称。将其称为Double.SMALLEST_POSITIVEMIN_INCREMENT等名称将更具语义清晰性。

此外,Doubles可以取到的最小值是多少?是-Double.MAX_VALUE吗?文档似乎没有提到。


2
谢谢回复!范围和精度之间的差异很有道理。我仍然觉得命名相当奇怪和不一致,但它是可行的。 - mo-seph
1
我猜这是由同样的天才编写的,他们称一个方法为writeBytes,但它却接受一个String - Hakanai
1
基本上,你是对的,这是糟糕的语义。 - Alvaro
6个回答

217
IEEE 754格式有一位保留符号,其余位表示幅度。这意味着它在原点周围是“对称的”(与整数值相反,整数值有一个更小的负值)。因此,最小值就是最大值,符号位取反,所以是的,-Double.MAX_VALUE是您可以用double表示的最低实际数字。
我认为Double.MAX_VALUE应该被视为最大幅度,在这种情况下,直接写-Double.MAX_VALUE实际上是有意义的。这也解释了为什么Double.MIN_VALUE是最小正值(因为它表示最小可能的幅度)。
但是,我同意命名有点误导。习惯于Integer.MIN_VALUE的含义,当我读到Double.MIN_VALUE是可以表示的最小绝对值时,我也有点惊讶。也许他们认为将最小可能值表示为它只需要一个 - ,因此这是多余的 :-)
(请注意,还有Double.NEGATIVE_INFINITY,但我不考虑它,因为它被视为“特殊情况”,实际上并不代表任何实际数字。) 这里有一篇关于这个主题的好文章。

4
谢谢。我正在将一些统计分析代码从Java翻译成C#,但盲目地进行翻译时发现一些数字输出为负无穷大或NaN,于是我仔细检查了算法。我意识到在这个上下文中double.MIN_VALUE毫无意义,因此进行了搜索。这篇帖子先于Java文档出现,它的确是一个令人困惑的名称,实际上应该是double.Epsilon。虽然这不是一个大问题,但只需要不到一分钟就可以解决,但确实让人感到惊讶。 - Ed S.
“最小可表示的绝对值”不应该被命名为“epsilon”吗? - Dave Cousineau
@Sahuagin,它并没有被“预定”为任何特定的名称。Epsilon只是希腊字母中常用于表示数学/物理中任意小的正量。例如,Go选择了SmallestNonzeroFloat64 - aioobe

14

这些常量与符号无关。如果将double视为三个部分的组合:符号、指数和尾数,则更有意义。 Double.MIN_VALUE实际上是指数在最小值时尾数可以采用的最小值,之后发生向零溢出。同样,MAX_VALUE可以理解为指数在最大值时尾数可以采用的最大值,然后发生向无穷大溢出。

对于这两个常量,一个更具描述性的名称可以是最大绝对值(为了冗长可以添加非零)和最小绝对值(为了冗长可以添加非无穷大)。

有关详细信息,请参见IEEE 754(1985)标准。有一种修订版(2008),但它只引入了更多格式,甚至没有被Java支持(严格来说,Java甚至缺少对IEEE 754 1985的某些强制性功能的支持,就像许多其他高级语言一样)。


7
我认为这些令人困惑的名称可以追溯到C语言,它将FLT_MIN定义为最小的正数。

就像在Java中,你必须使用-Double.MAX_VALUE一样,在C语言中,你必须使用-FLT_MAX来获取最小的浮点数。


5

双精度浮点数的最小值为Double.NEGATIVE_INFINITY,这就是为什么Double.MIN_VALUE并不是Double的真正最小值。

由于双精度浮点数是浮点数,因此您只能拥有最大的数字(具有较低的精度)或最接近0的数字(具有更高的精度)。

如果您确实想要一个非无穷大的双精度浮点数最小值,则可以使用-Double.MAX_VALUE


2
按照这个想法,Double类型的最大值是Double.MAX_VALUE还是Double.POSITIVE_INFINITY? - mo-seph
Double.MIN_VALUE 可能等于 Double.NEGATIVE_INFINITY - starblue
@starblue,不是的。@mo-seph,Double.POSITIVE_INFINITY,+∞ > 一切,而—∞ < 一切。 - Colin Hebert
@mo-seph 最大值为Double.POSITIVE_INFINITY - starblue
1
@ishtar,不确定我是否理解您的意思,Double.NEGATIVE_INFINITY < Double.NEGATIVE_INFINITY是false(显然),但是Double.NEGATIVE_INFINITY <= Double.NEGATIVE_INFINITY是true(显然)。 - aioobe
显示剩余3条评论

3

由于浮点数没有精确的范围,因此其精度是重要的。

/**
 * A constant holding the smallest positive nonzero value of type
 * <code>double</code>, 2<sup>-1074</sup>. It is equal to the
 * hexadecimal floating-point literal
 * <code>0x0.0000000000001P-1022</code> and also equal to
 * <code>Double.longBitsToDouble(0x1L)</code>.
 */

但我同意它应该有一个更好的名字 :)

好的,但是为什么有Double.MAX_VALUE是有意义的呢?这似乎是明确定义的。 - mo-seph
因为它是最精确的值(非无穷大),不考虑其符号。 - John Gardner

1

正如文件中所述,

Double.MIN_VALUE是一个常量,它保存了类型为double、最小的正数非零值2^(-1074)。

关键在于我们谈论的是浮点数表示。double数据类型是双精度64位IEEE 754浮点数。浮点数可以轻松地表示从1,000,000,000,0000.0000000000000001的数字,并在两端最大化精度(数字的位数)。 (更多内容请参见此处

尾数始终为正数,它包含浮点数的有效数字。指数表示尾数和符号应该乘以基数的正或负幂。这四个组成部分按照以下方式组合以获得浮点值。

enter image description here

认为MIN_VALUE是尾数可以表示的最小值。浮点表示的最小值是使用该值可以表示的最小大小。(可能应该使用更好的名称以避免这种混淆)
123> 10> 1> 0.12> 0.012> 0.0000123> 0.000000001> 0.0000000000000001
以下仅供参考。
双精度浮点可以表示2,098个二次幂,从2 ^ -1074到2 ^ 1023。二次幂非规格化是从2 ^ -1074到2 ^ -1023; 规格化的二次幂是从2 ^ -1022到2 ^ 1023。请参阅thisthis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接