如何在CPU内部存储浮点数?

Yat*_*ore 4 floating-point assembly ieee-754

我是一个初学者,正在学习组装基础知识。现在,在阅读此问题时,我来到了这一段。它说明了如何将浮点数存储在内存中。

浮点数的指数是8位字段。为了允许存储大数或小数,将指数解释为正数或负数。实际指数是8位字段的值减去127。127是32位浮点数的“指数偏差”。浮点数的分数字段让人有些意外。由于将0.0定义为所有设置为0的位,因此无需担心将0.0表示为等于127的指数字段并将小数字段设置为所有O。所有其他数字至少具有一个1位,因此IEEE 754格式使用隐式1位来节省空间。因此,如果小数字段为00000000000000000000000,则将其解释为1。00000000000000000000000。这允许分数字段有效地为24位。

我一点都不明白。

您能解释一下它们如何存储在内存中吗?我不需要参考,我只需要一个很好的解释即可轻松理解。

Mar*_*ara 5

浮点数遵循IEEE754标准。他们之所以使用这套规则,主要是因为浮点数可以(相对)轻松地与整数和其他浮点数进行比较。

有2种常见的浮点版本:32位(IEEE binary32 aka单精度float)和64位(binary64 aka doubleprecision)。它们之间的唯一区别是它们的字段大小:

  • 指数:32位为8位,64位为11位
  • 尾数:32位为23位,64位为52位

还有一个附加位,即符号位,用于指定所考虑的数字是正数还是负数。

现在,以12,37510 为基数(32位)为例:

  • 第一步是将这个数字转换为基数2:这很简单,经过一些计算,您将获得: 1100.011

  • 接下来,您必须移动“逗号”直到得到1.100011(直到.1 之前的唯一数字是1)。我们将逗号移动多少次?3,那是指数。这意味着我们的数字可以表示为1.100011*2^3。(由于它是二进制的,所以不称为小数点。这是“基数点”或“二进制点”。)

    移动.尾数(并用指数计数那些移动),直到尾数以超前开始为止1.被称为“归一化”。太小而无法以这种方式表示的数字(指数的有限范围)称为次正规数或非正规数。

  • 之后,我们必须对指数增加偏倚。32位浮点数中的8位指数字段为127。我们为什么要这样做?很好的答案是:因为这样我们可以更轻松地将浮点数与整数进行比较。(将FP位模式比较为整数会告诉您哪个具有更大的幅度(如果它们具有相同的符号)。)而且,递增位模式(包括从尾数到指数的进位)会将幅度增加到下一个可表示的值。(nextafter()

    如果我们不这样做,则负指数将使用二补码表示,实际上将1放在最高有效位。但是通过这种方式,较小的浮点似乎大于正指数的浮点。出于这个原因:我们只加127,在这个小技巧的情况下,所有正指数都从10000000基数2(即1个基数10)开始,而负数指数最大达到01111110基数2(即-1基数10)。

在我们的示例中,归一化指数为100000102。

(第一位是符号位)

有一个不错的在线转换器,它可以可视化32位浮点数的位,并显示其代表的十进制数。您可以修改其中一个,它也可以更新另一个。 https://www.h-schmidt.net/FloatConverter/IEEE754.html


那是简单的版本,这是一个好的开始。它通过省略来简化:

  • 非数字NaN(有偏指数=全1;尾数= 0)
  • +-无穷(有偏指数=全1,尾数= 0)
  • 并没有过多提及次正规数(有偏指数= 0表示尾数中的前导0而不是正常1)。

Wikipedia上有关单精度和双精度的文章非常出色,其中包含图表以及对极端情况和细节的大量解释。请参阅他们以获取完整的详细信息。

另外,某些(大多数是历史性的)计算机使用的不是FP-格式的IEEE-754。

还有其他IEEE-754格式,例如16位半精度,一种值得注意的扩展精度格式是80位x87,它显式存储有效位数的前导1,而不是用零或非零指数来表示。

IEEE-754甚至定义了一些十进制浮点格式,使用10 ^ exp精确表示十进制小数而不是二进制小数。(对这些硬件的支持有限,但确实存在)。

  • 为什么要用科学记数法写十进制数?原因是一样的。 (2认同)