assembly - float 如何存储在 CPU 中?

标签 assembly floating-point ieee-754

我是初学者,正在学习组装基础知识。现在在阅读这件事的时候,我来到了这一段。它解释了浮点数如何存储在内存中。

The exponent for a float is an 8 bit field. To allow large numbers or small numbers to be stored, the exponent is interpreted as positive or negative. The actual exponent is the value of the 8 bit field minus 127. 127 is the "exponent bias" for 32 bit floating point numbers. The fraction field of a float holds a small surprise. Since 0.0 is defined as all bits set to 0, there is no need to worry about representing 0.0 as an exponent field equal to 127 and fraction field set to all O's. All other numbers have at least one 1 bit, so the IEEE 754 format uses an implicit 1 bit to save space. So if the fraction field is 00000000000000000000000, it is interpreted as 1 . 00000000000000000000000. This allows the fraction field to be effectively 24 bits. This is a clever trick made possible by making exponent fields of OxOO and OxFF special.



我根本不明白。

你能解释一下它们是如何存储在内存中的吗?我不需要引用,我只需要一个很好的解释,这样我就可以很容易地理解。

最佳答案

浮点数跟随 the IEEE754 standard .他们一直在使用这组规则,主要是因为浮点数也可以(相对)容易地与整数和其他浮点数进行比较。

浮点数有 2 个常见版本:32 位( IEEE binary32 aka single-precision float )和 64 位( binary64 aka double precision )。它们之间的唯一区别是字段的大小:

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

  • 还有一个额外的位,符号位,它指定所考虑的数字是正数还是负数。

    现在,以 12,375 为例基数 10(32 位):
  • 第一步是以2为基数转换这个数字:
    很简单,经过一些计算你会得到:1100.011
  • 接下来你必须移动“逗号”直到你得到 1.100011 (直到 . 之前的唯一数字是 1)。我们移动逗号多少次? 3,那是指数。这意味着我们的数字可以表示为 1.100011*2^3 . (它不被称为小数点,因为它是二进制的。它是一个“小数点”或“二进制点”。)

    搬家 .大约(并用指数计算这些移动)直到尾数以领先的 1. 开头。被称为“规范化”。太小而无法以这种方式表示的数字(指数的有限范围)称为次正规数或非正规数。
  • 之后,我们必须将偏差添加到指数。对于 32 位浮点数中的 8 位指数字段,这是 127。我们为什么要这样做?答案是:因为这样我们可以更轻松地将浮点数与整数进行比较。 (将 FP 位模式与整数进行比较会告诉您哪个具有更大的幅度,如果它们具有相同的符号。)此外,增加位模式(包括从尾数到指数的进位)将幅度增加到下一个可表示的值。 ( nextafter() )

    如果我们不这样做,负指数将使用两个补码表示法表示,基本上在最高有效位中放置 1。但通过这种方式,较小的浮点似乎大于正指数浮点。出于这个原因:我们只需添加 127,通过这个小“技巧”​​,所有正指数都从 10000000 开始base 2 (即 1 base 10) 而负指数最多达到 01111110基数 2(即 -1 基数 10)。

  • 在我们的例子中,归一化指数是 10000010基地 2。
  • 最后要做的是在指数后添加 mantix ( .100011 ),结果是:
    01000001010001100000000000000000
     |  exp ||      mantix         |
    

  • (第一位是符号位)

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

    这是一个简单的版本,这是一个好的开始。它通过省略来简化:
  • 非 A 数 NaN(有偏指数 = 全 1;尾数 != 0)
  • +-无穷大(有偏指数 = 全 1;尾数 = 0)
  • 并没有说太多关于次正规数(偏置指数 = 0 意味着尾数中的前导 0 而不是正常的 1)。

  • 维基百科关于单精度和 double 的文章非常好,有图表和大量对极端情况和细节的解释。有关完整的详细信息,请参阅它们。

    此外,一些(主要是历史)计算机使用非 IEEE-754 的 FP 格式。

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

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

    关于assembly - float 如何存储在 CPU 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45073141/

    相关文章:

    c++ - Kahan算法中的加法而不是减法

    c++ - 使用程序集调试资源中的字符串

    go - 乘以 *float32 和 int 值

    c# - 在 C# 中格式化 double 输出

    java - 两个值之间唯一 `double` 的数量

    binary - 从二进制转换为 IEEE 浮点

    c - 识别使 double 方程 x + a == b 为真的最小和最大 x 的最快算法

    gcc - GNU 汇编程序指令的文档

    assembly - 编译为汇编时最小化跳转量

    c - NASM 堆栈错误?简单的乘法程序