【问题标题】:How does a 32-bit machine compute a double precision number32位机器如何计算双精度数
【发布时间】:2015-08-24 06:39:38
【问题描述】:

如果我只有 32 位机器,cpu 是如何计算双精度数的?这个数字是 64 位宽的。 FPU 如何处理它?

更普遍的问题是,如何计算更宽的东西,然后是我的 alu。但是我完全理解整数方式。你可以简单地split他们。然而,对于浮点数,您有指数和尾数,应该以不同的方式处理。

【问题讨论】:

  • 它只是比int64复杂,但可以处理2个32位数据。

标签: c++ double hardware


【解决方案1】:

并非“32 位机器”中的所有内容都必须是 32 位。 x87 风格的 FPU 从一开始就不是“32 位”的,那是在 AMD64 创建之前的很长一段时间。它总是能够在 80 位扩展双精度上进行数学运算,而且它曾经是一个单独的芯片,所以根本没有机会使用主 ALU。

它比 ALU 更宽,是的,但它不通过 ALU,浮点单元使用它们自己的电路,这些电路尽可能宽。这些circuits 也比整数电路复杂得多,并且它们与组件中的整数 ALU 并没有真正重叠

【讨论】:

  • 好吧,我就是这么想的。要么是 FPU 能够做到,因为它的设计几乎没有额外的东西,要么它是由软件完成的,这解决了编译器问题
【解决方案2】:

计算机体系结构中有几个不同的概念可以用比特来衡量,但它们都不能阻止处理 64 位浮点数。尽管这些概念可能相互关联,但对于这个问题,值得单独考虑它们。

通常,“32 位”表示地址为 32 位。这将每个进程的虚拟内存限制为 2^32 个地址。这是对程序产生最直接影响的度量,因为它影响指针的大小和内存中数据的最大大小。它与浮点数的处理完全无关。

另一个可能的含义是在内存和 CPU 之间传输数据的路径的宽度。这不是对数据结构大小的硬性限制——一个数据项可能需要多次传输。例如,Java 语言规范不需要doublelong 的原子加载和存储。见17.7. Non-Atomic Treatment of double and longdouble 可以使用两个单独的 32 位传输在内存和处理器之间移动。

第三个含义是通用寄存器大小。许多架构为浮点使用单独的寄存器。即使通用寄存器只有 32 位,浮点寄存器也可以更宽,或者可以将两个 32 位浮点寄存器配对来表示一个 64 位数字。

这些概念之间的典型关系是,具有 64 位内存地址的计算机通常会有 64 位通用寄存器,因此一个指针可以放在一个通用寄存器中。

【讨论】:

    【解决方案3】:

    即使是 8 位计算机也提供扩展精度(80 位)浮点运算,通过编写代码进行计算。

    现代 32 位计算机(x86、ARM、旧 PowerPC 等)具有 32 位整数和 64 位或 80 位浮点硬件。

    【讨论】:

    • 如果 32 位计算机只有 32 位浮点硬件呢?然后怎样呢? (这就是有趣的部分:)
    【解决方案4】:

    让我们先看看整数运算,因为它更简单。在您的 32 位 ALU 内部,有 32 个带有进位位的独立逻辑单元,它们会溢出链。 1 + 1 -> 10,进位但结转到第二个逻辑单元。整个 ALU 也将有一个进位输出,您可以使用它来进行任意长度的数学运算。但是宽度的唯一真正限制是您可以在一个周期中使用多少位。要进行 64 位数学运算,您需要 2 个或更多周期,并且需要自己执行进位逻辑。

    【讨论】:

    • 是的,我明白这一点,正如我已经写的那样。但它是如何处理浮点数的?没那么简单,因为这个数字在内部分为指数和尾数。
    • @hr0m 你将它们分开,然后使用这些任意精度例程对有效数字进行数学运算。指数和符号很容易适合普通类型。手动进行所有标准化和舍入等有点复杂,但可以完成。基本上,遵循硬件算法,但以更软件化的方式(迭代和分支)。
    【解决方案5】:

    似乎问题只是“FPU 是如何工作的?”,而不考虑位宽。

    FPU 做加法、乘法、除法等,每个都有不同的算法。

    加法

    (也是减法)
    给定两个带指数和尾数的数字:

    • x1 = m1 * 2 ^ e1
    • x2 = m2 * 2 ^ e2

    ,第一步是归一化:

    • x1 = m1 * 2 ^ e1
    • x2 = (m2 * 2 ^ (e2 - e1)) * 2 ^ e1(假设 e2 > e1)

    然后可以添加尾数:

    • x1 + x2 = (whatever) * 2 ^ e1

    然后,应该将结果转换为有效的尾数/指数形式(例如,(无论)部分可能需要在 2^23 和 2^24 之间)。如果我没记错的话,这称为“重整化”。这里还应该检查溢出和下溢。

    乘法

    只需将尾数相乘并添加指数即可。然后重新归一化相乘的尾数。

    部门

    对尾数执行“长除法”算法,然后减去指数。可能不需要重新规范化(取决于您如何实现长除法)。

    正弦/余弦

    将输入转换为范围 [0...π/2],然后对其运行 CORDIC 算法。

    【讨论】:

    • 不,问题是,这是否可以在硬件中完成,即使在 32 位计算机上也是如此。我理解数学概念。我了解它是如何在软件中完成的。不过谢谢你的总结
    猜你喜欢
    • 2015-04-02
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多