不,这不是另一个"Why is (1/3.0)*3 != 1"个问题.
我最近读了很多关于浮点的书;具体地说,same calculation might give different results是如何在不同的架构或优化设置上运行的.
这是存储重播的视频游戏的一个问题,或者是peer-to-peer networked(与服务器客户端相反),它们依赖于所有客户端在每次运行程序时生成完全相同的结果——一个浮点计算中的微小差异可能会导致不同机器(甚至on the same machine!)上的游戏状态截然不同
即使在"跟随"IEEE-754的处理器中也会发生这种情况,主要是因为某些处理器(即x86)使用double extended precision.也就是说,它们使用80位寄存器来执行所有计算,然后截断为64位或32位,从而导致不同于使用64位或32位进行计算的机器的舍入结果.
我已经在网上看到了这个问题的几种解决方案,但都是C++,而不是C语言:
- 使用
_controlfp_s
(Windows)、_FPU_SETCW
(Linux?)和,或fpsetprec
(BSD). - 始终以相同的优化设置运行相同的编译器,并要求所有用户具有相同的CPU架构(无跨平台播放).因为我的"编译器"实际上是JIT,它是may optimize differently every time the program is run,我认为这是不可能的.
- 使用定点运算,同时避免
float
和double
.decimal
可以用于此目的,但是速度会慢得多,并且System.Math
个库函数中没有一个支持它.
那么,如果我只打算支持Windows(而不是Mono)呢?
如果是,is there any way to force my program to run at normal double-precision?
如果不是,are there any libraries that would help保持浮点计算的一致性?