浮点数学在C#中是一致的吗?可以吗?
不,这不是另一个“为什么(1/3.0)*3!=1”问题。
最近我读了很多关于浮点数的文章,特别是,相同的计算可能会给出不同的结果。在不同的架构或优化设置上。
对于存储重播的电子游戏来说,这是一个问题。点对点联网(相对于服务器-客户机),每次运行程序时,所有客户端都会产生完全相同的结果-一个浮点计算中的微小差异可能会导致不同机器上的游戏状态(甚至是完全不同的游戏状态)。在同一台机器上!)
即使在“跟随”处理器中也会发生这种情况。IEEE-754,主要是因为一些处理器(即x86)使用双扩展精度..也就是说,他们使用80位寄存器来做所有的计算,然后截断到64位或32位,导致与使用64位或32位的机器不同的四舍五入结果。
我在网上看到了几种解决这个问题的方法,但都是针对C+的,而不是C#:
- 禁用双扩展精度模式(使所有
double
计算使用IEEE-754 64位)_controlfp_s
(窗户)_FPU_SETCW
(Linux?)fpsetprec
(BSD)。 - 始终使用相同的优化设置运行相同的编译器,并要求所有用户具有相同的CPU架构(没有跨平台播放)。因为我的“编译器”实际上是JIT,它
每次运行程序时都可能以不同的方式进行优化。
我不认为这是可能的。 - 使用定点算法,避免
float
和double
总之。decimal
将为此目的工作,但速度要慢得多,而且没有一个System.Math
图书馆功能支持它。
所以,这在C#中是一个问题吗?如果我只打算支持Windows(而不是Mono)呢?
如果是的话,有没有办法强迫我的程序以正常的双精度运行?
如果不是,有没有图书馆能帮上忙保持浮点计算一致?