【问题标题】:Does single floating point operation calculated at higher precision and immediately truncated always produce identical result?以更高的精度计算并立即截断的单浮点运算是否总是产生相同的结果?
【发布时间】:2016-09-07 07:46:50
【问题描述】:

单浮点运算(如 a+b、a-b、a*b 或 a/b)是否以更高的精度(80 位)计算并立即截断(到 32 位)总是产生与原始类型的计算相同的结果精度(32 位)?

或者结果中的最低有效位会有所不同吗?为什么?

编辑:来自this blog post的部分示例

float tmp;  // 32 bit precision temporary variable
push a;     // converts 32 to 64 bit
push b;     // converts 32 to 64 bit
multiply;   // 64 bit computation
pop tmp;    // converts result to 32 bits

这个例子的作者是这样解释这段代码的:

即使乘法和加法指令使用 64 位内部精度,结果也会立即转换回 32 位格式,因此不会影响结果。

所以我要问的是,这总是正确的吗?像这样的单个操作,无论在什么平台上,总是会产生与最后一位相同的结果?

我正在使用 C# 进行编程,我们无法控制执行的精度浮点运算。

来自 C# 规范:

浮点运算的执行精度可能高于 操作的结果类型。例如,一些硬件 架构支持“扩展”或“长双精度”浮点 比双精度类型具有更大范围和精度的类型,并且 使用这个更高的隐式执行所有浮点运算 精度类型。

而且我需要知道浮点上的单个操作(如下面的 C# 示例)是否具有确定性。

double a = 2.5d;
double b = 0.1d;
myClassInstance.someDoubleField = a*b; // value should be converted out of extended precision 

那么someDoubleField 值在所有平台上都相同吗?

【问题讨论】:

  • 你的意思是“四舍五入”中的截断吗?或者您实际上是指通过“向最接近或什至”四舍五入来降低精度?对于后者,已发表的工作表明,如果较高的精度提供至少 2n+k 位而不是较低的 n 位精度(其中 k
  • 当值从扩展精度中弹出时截断。我已经用额外的解释更新了这个问题。
  • 不清楚你在这里问什么。你。将给定的操作序列与什么进行比较?
  • @EJP 在 FP 计算过程中使用更高的 FP 精度与在计算过程中使用相同精度(与使用的 FP 类型相同)相比它的行为

标签: floating-point deterministic


【解决方案1】:

是的,它在本文中成立:

Samuel A. Figueroa,“什么时候双舍入是无害的?” ACM SIGNUM 通讯,第 30 卷,第 3 期,1995 年 7 月 doi:10.1145/221332.221334

主要结果是如果输入类型有p-bit有效位,并且计算类型有效位的位数至少为2p+ 2位,基本运算+、-、*、/和sqrt在截回时都将正确舍入。

IEEE754 binary32 数字(即典型的 C float 类型)具有 24 位有效位,因此实际上使用具有 53- 的 binary64(即典型的 C double)就足够了位有效位。事实上,当语言本身只有 binary64 类型时,这是一个很常见的技巧 used by JavaScript compilers 使用 binary32 操作。

【讨论】:

  • 我已经更新了问题,并提供了额外的解释,因为 njuffa 要求进一步澄清我的意思。所以如果我可能会问,在使用 80 位扩展精度对两个 64 位双精度进行基本运算时是否也一样?
  • @zigzag 注意“2p+2”位的精度要求(如果包含倒数平方根,则为 2p+3)。当您考虑将 80 位扩展精度(带有 64 位有效数/尾数)舍入到双精度时,显然不满足。
  • 否(x87 80 位“长双精度”具有 64 位有效位,因此不满足该属性)。您可能需要使用编译器选项; C#有/fp:precisemsdn.microsoft.com/en-us/library/e7s85ffb.aspx
  • 只要 x87 是混合的一部分,这种逐位浮点一致性似乎不太可能(它是唯一提供扩展精度的常用浮点处理器)。如果硬件提供严格的 IEEE-754 binary32 和 binary64 计算,您的机会非常好,但即使在那里,您也可能会遇到障碍,具体取决于浮点单元是否在非 IEEE-754 刷新为零模式下运行.
  • 啊,我没有意识到那些是 C++ 文档。一般来说,您应该没问题,因为大多数编译器将在 x87 上使用 SSE 指令或 64 位模式:您还可以添加一些内联汇编来确保这种情况。
猜你喜欢
  • 2014-10-07
  • 1970-01-01
  • 1970-01-01
  • 2019-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
相关资源
最近更新 更多