相关疑难解决方法(0)

浮点数学在C#中是否一致?是真的吗?

不,这不是另一个"为什么是(1/3.0)*3!= 1"的问题.

我最近一直在读关于漂浮点的事情; 具体而言,相同的计算如何在不同的体系结构或优化设置上给出不同的结果.

对于存储重放的视频游戏来说,这是一个问题,或者是对等网络(而不是服务器 - 客户端),它依赖于每次运行程序时产生完全相同结果的所有客户端 - 一个小的差异浮点计算可能导致不同机器(甚至是同一台机器上)的游戏状态截然不同!

甚至在"跟随" IEEE-754的处理器中也会发生这种情况,这主要是因为某些处理器(即x86)使用双倍扩展精度.也就是说,它们使用80位寄存器进行所有计算,然后截断为64位或32位,导致与使用64位或32位进行计算的机器不同的舍​​入结果.

我在网上看到过这个问题的几种解决方案,但都是针对C++,而不是C#:

  • double使用_controlfp_s(Windows),_FPU_SETCW(Linux?)或fpsetprec(BSD)禁用双扩展精度模式(以便所有计算使用IEEE-754 64位).
  • 始终使用相同的优化设置运行相同的编译器,并要求所有用户具有相同的CPU架构(无跨平台播放).因为我的"编译器"实际上是JIT,它可能在每次运行程序时都有不同的优化,我认为这是不可能的.
  • 使用定点算术,避免floatdouble完全.decimal可以用于此目的,但会慢得多,并且没有任何System.Math库函数支持它.

那么,这在C#中是否也是一个问题? 如果我只打算支持Windows(而不是Mono)怎么办?

如果是,有没有办法强制我的程序以正常的双精度运行?

如果没有,是否有任何库可以帮助保持浮点计算的一致性?

.net c# floating-point precision ieee-754

152
推荐指数
6
解决办法
1万
查看次数

FP操作在各种x86 CPU上是否完全相同?

不同的x86 CPU(具有内置FPU和合理的最新版本,比如已推出这个千禧年)为其浮点基元产生完全相同的结果,假设在被比较的CPU上有相同的指令,相同的输入和相同的操作参数,例如舍入模式?我对时间上的差异感兴趣,也没有对Pentium FDIV错误感兴趣(因为那个事件很古老而不符合资格).

我猜对于加法,减法,否定和舍入到整数的答案是肯定的,因为它们具有精确的定义,我很难想象实现中的差异是什么(可能是检测溢出时的错误/下溢,但在某些应用程序中这将是一场灾难,所以我想这很久以前就已经被捕获并修复了).

乘法似乎更可能有不同的实现:确定两个DPFPN产品的(比如)最近可表示的双精度浮点数(64位,包括52 + 1尾数),有时需要计算其尾数的乘积(关于104位精度,对于少数LSBits来说,可以说是浪费精力.我想知道这是否尝试过,并且做得正确.或许IEEE-754或某些事实上的标准规定了什么?

师似乎更加微妙.

而且,除了常见的设计之外,我怀疑所有更复杂事物(trig函数,日志......)的实现都可以完全同步,因为可以使用各种数学方法.

我问的是纯粹的nosiness的结合; 愿意改善我的答案 ; 并期望一种方法(某些时候)允许在VM中运行的程序检测假装运行的CPU与真实CPU之间的不匹配.

x86 floating-accuracy

9
推荐指数
1
解决办法
685
查看次数

标签 统计

.net ×1

c# ×1

floating-accuracy ×1

floating-point ×1

ieee-754 ×1

precision ×1

x86 ×1