最小浮点数怎么可能是 2^(-126) ,而不是 2^(-128)

use*_*666 4 floating-point ieee-754

考虑一个 32 位浮点数(IEEE 754),尾数为 0-22(23 位),指数(8 位)为 23-30,符号(1 位)为 31
我想找出可以是的最小正数存储。
有人告诉我答案是 1.18*10 -38大约是 2 -126
我的分析如下,
如果我们将所有零放在尾数中并将所有 1 放在指数中,那么十进制等效值将是
1.0 x 2 -128 = 2.93 x 10 -39

我哪里出错了?
谢谢

Ste*_*mit 5

我认为 IEEE-754 数字分为三个主要类别:特殊数字、普通数字和次正常数字。这些类别基于指数值,每个类别内还有一些子结构。\n特殊类别是具有最大指数值的类别,次正规类别具有最小指数,而普通类别是介于两者之间的所有指数。我们可以将事情总结在一个表格中(这里的具体值是单精度的值)float您所询问的,这里的具体值是单精度的值):

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
指数有效数字类别调整后的有效数形容词 实验值。
FF非零*不适用
FF0无穷不适用不适用
01\xe2\x80\x93FE任何事物法线(1)000000\xe2\x80\x93(1)7fffff-126 \xe2\x80\x93 +127
00非零次正常000000\xe2\x80\x937fffff-126
0000不适用
\n
\n

关键是:

\n
    \n
  • 普通数有一个 24 位有效数(通常称为“尾数”),其中前导位始终为 1(因此是隐式的),指数范围为 -126 到 +127(即 到 或0x0110xfe到 254) ,减去 127 的偏差)。
  • \n
  • 次正规数具有 23 位有效数,其中前导位不一定为 1(因此是显式的),指数为 -126。
  • \n
\n

现在,您可能会认为对于次正规数,由于原始指数为 0,指数偏差为 127,因此实际指数应为 -127。(这也是我很长一段时间以来的想法。)但这会在次正常值中留下间隙。因此,次法线的指数为 -126,比您预期的高 1,并且最终与最小法线的指数匹配。

\n

那么这些范围的作用是什么?

\n

对于法线,最大原始有效数为0x7fffff, 或0xffffff添加隐式 1 位,其分数为0x1.fffffe, 或 1.99999988079071044921875。最小原始有效数为0x000000,或0x800000添加隐式 1 位,即0x1.000000, 或 1.0。

\n

对于次正规数,最大原始有效数为0x7fffff,其分数为0x0.fffffe, 或 0.99999988079071044921875。最小原始有效数是0x000001,即0x0.000002, 或 0.00000011920928955078125。

\n

将所有这些与最大和最小指数值放在一起,我们有:

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
临界点推导小数十六进制
最大正常值1.99999988\xc3\x97 2 1273.4028234663852885981e+380xf.fffff0E+31
最小正常值1.0 \xc3\x97 2 -1261.175494350822287508e-380x4.000000E-32
最大次正常0.99999988\xc3\x97 2 -1261.175494210692441075e-380x3.fffff8E-32
最小低于正常值0.000000119\xc3\x97 2 -1261.401298464324817071e-450x8.000000E-38
\n
\n

所以当你听说最小的float是 1.18 \xc3\x97 10 -38时,显然有人在谈论最小的法线数,而忽略了次正常数的存在。正如您所看到的,最小的次法线要小得多。

\n

在此表中,我们还可以看出为什么次正规数的指数必须是 -126,而不是 -127。次正常值应该覆盖最小正常值和零之间的范围。当指数为 -126 时,它们可以均匀且良好地做到这一点。另一方面,如果次正规数的指数为 -127,则最大次正规数将为 0.9999998 \xc3\x97 2 -127 = 5.877471053462205377e-39 或0x1.fffffcE-32,这已经是斜率到零的一半(可以这么说),其余的次正常值都挤在该值以下,在 1.175e-38 和 5.877e-39 之间留下了“大”差距。维基百科在“次正规数”页面上有一张漂亮的图片,说明了次正规数如何填补 0 附近的空白。

\n

另请参阅此问题,了解有关如何构造 IEEE-754 浮点值的更多信息。

\n
\n

脚注:我在这个答案中使用了类似的符号0x1.fffffe,这是一个以 16 为基数的分数,这当然不是你的 C 编译器会接受的。然后0xf.fffffE+31是十六进制科学记数法,其中指数是 16 的幂,并且E不是作为有效数一部分的十六进制数字。这有点像printf/scanf格式%a,尽管%a它用于p标记其指数,即 2 的幂。

\n