Double.MIN_NORMAL
(Java 1.6 中引入) 和有什么区别Double.MIN_VALUE
?
3 回答
答案可以在IEEE 浮点表示规范中找到:
对于单一格式,普通数和次正规数的区别在于,普通数的有效位(二进制小数点左边的位)的前导位是 1,而次正规数的有效位的前导位是 1。 number 为 0。单格式次正规数在 IEEE 标准 754 中称为单格式非规格化数。
换句话说,Double.MIN_NORMAL
是您可以表示的最小可能数字,前提是您在二进制点前面有一个 1(在十进制系统中称为小数点)。虽然Double.MIN_VALUE
基本上是您可以在没有此约束的情况下表示的最小数字。
IEEE-754 binary64 格式:
s_eee_eeee_eeee_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm
(1 s
; 3×4−1 =11 e
s; 64−3×4 =52 m
s)
, 及其算法:
如果
e >000_0000_0000
and<111_1111_1111
: 解释为(-1)
s ×2 e−balancer:1023 ×(
base:1 +m×2 −sub-one-pusher:52)
。(这些是正常数字。)If
e =000_0000_0000
: 做同样的事情(如上一行)除了base:1
isbase:0
和e
ise +1
。(这些是次正规数,除了零既不是次正规/正规。)If
e =111_1111_1111
andm =0000...0000
: 解释为(-1)
s × 无穷大。If
e =111_1111_1111
andm <>0000...0000
: 解释为 NaN。(顺便说一句:因此,NaN 有 2×(
2 52 -1)
种不同的位表示,参见#Quiet NaN &doubleToRawLongBits
。)
因此:
其可能的最小正数是
0_000_0000_0000_0000_..._0001
(Double.MIN_VALUE
(也是 .NET 的Double.Epsilon
))(次正规数)。其可能的正正规数中的最小者是
0_000_0000_0001_0000_..._0000
(Double.MIN_NORMAL
)。
附录:
MIN_VALUE
计算:
(-1) s:0 ×2 (e:0+1)−balancer:1023 ×(base:0 +m:1 ×2 −sub-one-pusher:52 )
= 1 ×2 -1022 ×2 -52
= 2 -1074 ( ~4.94 × 10 -324 )
,和MIN_NORMAL
计算:
(-1) s:0 ×2 e:1 −balancer:1023 ×(base:1 +m:0 ×2 −sub-one-pusher:52 )
= 1 ×2 -1022 ×1
= 2 -1022 ( ~2.225 × 10 -308 )
为简单起见,解释将仅考虑正数。
两个相邻的归一化浮点数'x1' 和 'x2'之间的最大间距是2 * epsilon * x1
(归一化浮点数不是均匀间隔的,它们是对数间隔的)。这意味着,当实数(即“数学”数)四舍五入为浮点数时,最大相对误差为epsilon
,这是一个称为机器 epsilon 或单位舍入的常数,对于双精度,它的值为 2 ^-52(近似值 2.22e-16)。
小于 的浮点数Double.MIN_NORMAL
称为次正规数,它们均匀地填充 0 和 之间的间隙Double.MIN_NORMAL
。这意味着涉及次正规的计算可能会导致不太准确的结果。当结果很小时,使用次正规允许计算更慢地失去精度。