【问题标题】:Why would the same code yield different numeric results on 32 vs 64-bit machines?为什么相同的代码在 32 位和 64 位机器上会产生不同的数值结果?
【发布时间】:2011-12-12 10:25:05
【问题描述】:

我们正在开发一个 C 中的数值例程库。我们还不确定我们是使用单精度 (float) 还是双精度 (double),因此我们定义了一个类型 SP在我们决定之前作为别名:

typedef float SP;

当我们运行我们的单元测试时,它们都在我的机器(64 位 Ubuntu)上通过,但在我同事的机器(32 位 Ubuntu,被错误地安装在 64 位机器上)上失败。

使用 Git 的 bisect 命令,我们找到了他的机器和我的机器之间开始产生不同结果的确切差异:

-typedef double SP;
+typedef float SP;

换句话说,从双精度到单精度在我们的机器上会产生数值上不同的结果(在最坏的情况下大约有 1e-3 的相对差异)。

我们相当肯定,我们永远不会在任何地方将无符号整数与负符号整数进行比较。

为什么数值例程库会在 32 位操作系统和 64 位系统上产生不同的结果?

澄清

恐怕我还不够清楚:我们有使用双精度的 Git 提交 2f3f671,并且单元测试在两台机器上都同样通过。然后我们有 Git 提交 46f2ba,我们更改为单精度,这里的测试 still 在 64 位机器上通过,但在 32 位机器上 .

【问题讨论】:

  • 你确定这是操作系统的问题而不是硬件差异?
  • 可能是因为这个:stackoverflow.com/questions/1076190/…,(32位代码使用387协处理器,64位代码可能使用sse)
  • nos 是唯一一个做对的人。给出的答案是错误的。
  • 鉴于 nos 的评论,您可能应该研究优化选项对代码正确性的影响。 Gcc 有一些处理浮点操作的行为。尝试阅读生成的汇编程序,看看这两种架构之间是否存在显着差异。

标签: c floating-point


【解决方案1】:

您遇到了通常称为“x87 超精度“错误”的问题。

简而言之:从历史上看,(几乎)x86 处理器上的所有浮点计算都是使用 x87 指令集完成的,该指令集默认运行在 80 位浮点类型上,但可以设置为在任一单- 或控制寄存器中的某些位(几乎)双精度。

如果在 x87 控制寄存器的精度设置为双精度或扩展精度时执行单精度操作,则结果将与以单精度执行相同操作时产生的结果不同(除非编译器非常小心,会存储每次计算的结果并重新加载它以强制在正确的位置进行舍入。)

您在 32 位上运行的代码使用 x87 单元进行浮点计算(显然控制寄存器设置为双精度),因此遇到了上述问题。您在 64 位上运行的代码使用 SSE[2,3,...] 指令进行浮点计算,该指令提供本机单精度和双精度运算,因此不携带超精度。这就是您的结果不同的原因。

您可以通过告诉您的编译器即使在 32 位(-mfpmath=sse 与 GCC)上使用 SSE 进行浮点计算来解决这个问题(在一定程度上)。即使这样,也不能保证精确到位的结果,因为您链接的各种库可能使用 x87,或者只是根据架构使用不同的算法。

【讨论】:

  • 天哪,你是对的。添加-mfpmath=sse(但与-msse 一起,根据gcc 手册页)使其在32 位机器上传递。谢谢谢谢谢谢谢谢
  • 您是否有任何关于他们为什么从 FPU 转移到 SSE 的文章的链接?
  • @Skizz:没有链接,但是“因为它几乎在所有方面都更好。” SSE 不会受到超精度的影响,可以舍入到更小的类型而不需要存储,更好地支持处理 NaN,速度更快,没有那么多隐藏的停顿,支持浮点和整数之间的转换,需要更少的内存流量, ...
【解决方案2】:

IIRC,'double' 的精度只是 要求>= 'float' 的精度。因此,在一种实现中,“float”和“double”中的实际位数可能相同,而在另一种实现中则不同。这可能与平台的 32 位/64 位差异有关,但可能不是。

【讨论】:

  • 投反对票是怎么回事?!我指的是浮点和双精度类型的 C 语言定义。这些不必映射到 IEEE 754 单精度和双精度类型。只要 double 的精度优于或等于 float 的精度,实现就符合 C 规范
猜你喜欢
  • 2011-10-31
  • 2019-07-08
  • 2011-04-30
  • 2015-08-27
  • 1970-01-01
  • 2016-02-26
  • 1970-01-01
  • 2017-04-22
  • 2014-05-08
相关资源
最近更新 更多