Double.MIN_NORMAL和Double.MIN_VALUE之间的区别?

我可以知道Double.MIN_NORMAL (1.6中介绍)和Double.MIN_VALUE之间有什么区别吗?

Double.MIN_NORMAL JavaDoc:

一个常量保持最小的正常值typesdouble ,2 -1022

Double.MIN_VALUE JavaDoc:

一个常量保持最小的正数非零值typesdouble ,2 -1074

答案可以在IEEE浮点表示规范中find:

对于单一格式,正常数字和次正常数字之间的差别在于,正常数字的有效位的前导位(二进制位的左边的位)是1,而低于正常数的有效位的前导位数字为0.在IEEE标准754中,单格式的非正常数字被称为单格式非正规化数字。

换句话说, Double.MIN_NORMAL是可以表示的最小可能数字,只要在二进制点前面有一个1(在十进制系统中被称为小数点)即可。 而Double.MIN_VALUE基本上是没有这个约束的情况下可以表示的最小数字。

Tldr:

Double.MIN_NORMAL给出了最小的正IEEE-754二进制64 “ 正常数 ”(也称为标准化数)。 这等于2 -1022 ,大约是2.225×10 -308

Double.MIN_VALUE给出最小的正IEEE-754二进制64“ 次正常数 ”(也称为非规格化或次正规数)。 这相当于2 -1074 ,大约是4.94×10 -324 。 (这也是.NET的Double.Epsilon给出的Double.Epsilon 。)

TSDR:

要理解为什么这些数字是他们是什么,他们之间有什么区别,我们将不得不更深入。 (也请阅读Bosonix的答案。)

考虑IEEE-754二进制64格式的比特表示:

 s_eee_eeee_eeee_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm 

IEEE-754的binary64值是这样得出的:

  • 如果e大于0 小于2047(2047是二进制的111_1111_1111 ),

    那么值等于(-1) s × 2e-1023 ×(1 + m× 2-52 )。 (这是正常的数字。)

  • 如果e等于0,

    那么值等于(-1) s ×2 (e + 1)-1023 ×(0 + m× 2-52 )。 (除零之外,这些是次正常数字。)

  • 如果e等于2047并且m等于0,

    那么值等于(-1) s × 无穷大

  • 如果e等于2047并且m不等于0,

    那么值等于NaN。 (不相关的事实:因此NaN有2×(2 52 – 1)个不同的位表示 ;参见doubleToRawLongBits 。)

因此,最小的正IEEE-754二进制64正常数等于:

(-1) 0 ×2 1-1023 ×(1 + 0×2 -52

= 2 -1022

而最小的正IEEE-754二进制64次正常数等于:

(-1) 0 ×2 (0 + 1)-1023 ×(0 + 1×2 -52

= 2 -1022 ×2 -52

= 2 -1074

为了简单起见,解释只考虑正数。

两个相邻的归一化浮点数 “x1”和“x2”之间的最大间隔是2 * epsilon * x1 (归一化浮点数不是均匀间隔的,它们是对数间隔的)。 这意味着,当一个实数 (即“math”数)四舍五入到一个浮点数时,最大相对误差epsilon ,它是一个称为机器ε或单位舍入的常量,对于双精度,它具有值2 ^ -52(近似值2.22e-16)。

小于Double.MIN_NORMAL的浮点数称为次正规,它们均匀填充0到Double.MIN_NORMAL之间的间隔。 这意味着涉及低于正常值的计算会导致不准确的结果。 当结果很小时,使用低于正常的标准可以使计算更加缓慢地失去精度。