Delphi中的浮点运算是否具有确定性?

时间:2014-06-22 14:08:24

标签: delphi floating-point cross-platform precision deterministic

Delphi中的浮点运算是否具有确定性?

即。我将使用Delphi Win32编译器编译的相同可执行文件中的相同浮点数学运算得到相同的结果,就像我使用Win64编译器,OS X编译器,iOS编译器或Android编译器一样?

这是一个至关重要的问题,因为我正在我的游戏引擎中实现多人游戏支持,我担心客户端的预测结果可能经常与服务器的确定(和权威)决定不同。 / p>

当权威游戏状态数据否决客户端的预测状态时,其结果是客户端出现“滞后”或“急躁”。

由于我实际上没有能力在不同编译器上编译的不同平台上测试数十种不同的设备,而这些设备类似于“受控条件”,我认为最好将这个问题提交给Delphi的开发人员。看看是否有人对编译器的低级浮点确定性有内部理解。

3 个答案:

答案 0 :(得分:6)

我认为没有简单的答案。讨论了类似的任务here。 通常,浮点数的表示有两个标准: IEEE 754-1985和EEE 754-2008。 所有现代(实际上很老)的CPU都遵循标准,它保证了一些东西:

  • 相同标准浮动类型的二进制表示将相等
  • 某些操作的结果(并非所有操作,只有基本操作!)保证相等,但只有编译器使用相同类型的命令时,我才不确定是否为真。

但是如果使用某些扩展操作(例如平方根),即使对于不同型号的桌面CPU,结果也可能会有所不同。您可以阅读这篇文章了解一些细节: http://randomascii.wordpress.com/2013/07/16/floating-point-determinism/

P.S。正如tmyklebu所提到的,平方根也是由IEEE 754定义的,因此可以为Add,Subtract,Multiply,Divide和Square root的相同输入保证相同的结果。 IEEE还定义了很少的其他操作,但是对于所有细节,最好阅读IEEE。

答案 1 :(得分:2)

暂时不考虑浮点计算的标准,考虑32位和64位编译器编译使用旧FPU与较新的SSE指令。我会发现很难相信每个计算在不同的硬件实现上总会完全相同。最好走安全路线并假设如果它在一个小的delta pf差异内,你评价为相等。

答案 2 :(得分:1)

根据经验,我可以看出结果是不同的:32位默认使用扩展精度,而64位默认使用双精度。

考虑声明

x,y,z:double; x:= y * z;

在Win32中

将执行“x:= double(Extended(y)* Extended(z)); 在Win64中,这将执行为“x:= double(double(y)* double(z));

您需要付出很多努力来确保使用相同的精度和模式。但是,无论何时调用第三方库,都需要考虑它们可能在内部更改这些标记。