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

时间:2016-09-07 07:46:51

标签: floating-point deterministic

以更高精度(80位)计算并立即截断(至32位)的单浮点运算(如a + b,ab,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

此示例的作者解释了这样的代码:

  

即使乘法和加法指令使用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值在所有平台上都是相同的吗?

1 个答案:

答案 0 :(得分:2)

是的,它已在本文中确定:

  塞缪尔·菲格罗亚(Samuel A. Figueroa),“什么时候是双重无伤害?” ACM SIGNUM Newsletter ,Volume 30 Issue 3,July 1995 doi:10.1145/221332.221334

主要结果是,如果输入类型具有 p 位有效位数,并且计算类型的有效位数中的位数至少为2

+ 2位,基本操作+-*/sqrt在被截断时都会被正确舍入。

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