以更高的精度计算并立即截断的单个浮点运算是否总是产生相同的结果?

Does single floating point operation calculated at higher precision and immediately truncated always produce identical result?

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

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

Even though the multiply and add instructions are using 64 bit internal precision, the results are immediately converted back to 32 bit format, so this does not affect the result.

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

我在 C# 中编程,我们无法控制完成的精度浮点运算。

来自 C# 规范:

Floating-point operations may be performed with higher precision than the result type of the operation. For example, some hardware architectures support an “extended” or “long double” floating-point type with greater range and precision than the double type, and implicitly perform all floating-point operations using this higher precision type.

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

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

那么这个 someDoubleField 值在所有平台上是否都相同?

是的,在本文中成立:

Samuel A. Figueroa, "When is double rounding innocuous?" ACM SIGNUM Newsletter, Volume 30 Issue 3, July 1995 doi:10.1145/221332.221334

主要结果是如果输入类型有p位尾数,计算类型尾数的位数至少为2p+2位,初等运算+-*/sqrt在截断时都会正确舍入返回。

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