是浮点运算在C#中是否一致?这可以吗? [英] Is floating-point math consistent in C#? Can it be?

查看:141
本文介绍了是浮点运算在C#中是否一致?这可以吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

没有,这是不是另一种的为什么(1 / 3.0)* 3!= 1的问题。

No, this is not another "Why is (1/3.0)*3 != 1" question.

我一直在阅读有关浮动点了很多最近;具体而言,如何在同样的计算可能会得出不同的结果在不同的体系结构和优化设置。

I've been reading about floating-points a lot lately; specifically, how the same calculation might give different results on different architectures or optimization settings.

这是视频游戏用来存储回放,或者的对等联网(相对于服务器的客户端),它依赖于产生恰好每次运行程序时相同的结果的所有客户端 - 在一个浮点运算的小差异会导致在不同的机器一个截然不同的游戏状态(甚至在同一台机器!

This is a problem for video games which store replays, or are peer-to-peer networked (as opposed to server-client), which rely on all clients generating exactly the same results every time they run the program - a small discrepancy in one floating-point calculation can lead to a drastically different game-state on different machines (or even on the same machine!)

这会发生,即使当中的跟随处理器 IEEE-754 ,主要是因为一些处理器(即x86)的使用双扩展precision 。也就是说,他们使用80位寄存器来完成所有的计算,然后截断为64位或32位,从而导致不​​同的舍入的结果比它使用64位或32位计算的机器。

This happens even amongst processors that "follow" IEEE-754, primarily because some processors (namely x86) use double extended precision. That is, they use 80-bit registers to do all the calculations, then truncate to 64- or 32-bits, leading to different rounding results than machines which use 64- or 32- bits for the calculations.

我已经看到了一些解决问题的对策在线,但所有的C + +,而不是C#:

I've seen several solutions to this problem online, but all for C++, not C#:

  • 在禁止双延伸期precision模式(让所有的计算使用IEEE-754 64位),使用的 _controlfp_s (Windows)中, _FPU_SETCW (Linux呢?),或者的 fpset preC (BSD)。
  • 始终运行在相同的编译器使用相同的优化设置,并要求所有用户都具有相同的CPU体系结构(没有跨平台的游戏)。因为我的编译实际上是JIT,其中可能每次程序运行时优化不同,我不认为这是可能的。
  • 使用定点运算,避免浮动干脆。 十进制将努力为这个目的,但会慢得多,并且没有任何的 System.Math 的库函数支持
  • Disable double extended-precision mode (so that all double calculations use IEEE-754 64-bits) using _controlfp_s (Windows), _FPU_SETCW (Linux?), or fpsetprec (BSD).
  • Always run the same compiler with the same optimization settings, and require all users to have the same CPU architecture (no cross-platform play). Because my "compiler" is actually the JIT, which may optimize differently every time the program is run, I don't think this is possible.
  • Use fixed-point arithmetic, and avoid float and double altogether. decimal would work for this purpose, but would be much slower, and none of the System.Math library functions support it.

因此​​,是这样的,即使在C#中的问题?如果我只打算支持Windows(不是单声道)?

So, is this even a problem in C#? What if I only intend to support Windows (not Mono)?

如果是,有没有办法强迫我的程序在正常的双precision运行?

如果不是,是否有任何库,这将有助于保持浮点运算一致?

If not, are there any libraries that would help keep floating-point calculations consistent?

推荐答案

据我所知,没有办法的方式,使正常的浮点确定在.NET。抖动允许创建code时会有不同行为在不同的平台(或不同版本的.NET之间)。因此,使用普通的浮动 S在确定.NET code是不可能的。

I know of no way to way to make normal floating points deterministic in .net. The JITter is allowed to create code that behaves differently on different platforms(or between different versions of .net). So using normal floats in deterministic .net code is not possible.

的变通方法我认为是:

  1. 在C#实现FixedPoint32。虽然这不是太硬(我有一个半完成的实现)的非常小的范围内的值使得恼人使用。你必须要小心,在任何时候,所以你既没有溢出,也没有失去太多precision。最后,我发现比直接使用整数这并不容易。
  2. 在C#实现FixedPoint64。我发现这相当困难的事情。对于某些操作的128bit的中间整数将是有益的。但是,.NET并没有提供这样一种类型。
  3. 实现自定义的32位浮点。实施这个当BitScanReverse内在的缺乏导致了一些烦恼。但目前我认为这是最有前途的道路。
  4. 使用本地code的数学运算。会在每一个数学运算的委托调用的开销。

我刚开始软件实施的32位浮点运算。它可以在我的2.66GHz的酷睿i3做每秒约7000加法/乘法。 https://github.com/$c$csInChaos/SoftFloat 。显然,这仍然是非常不完整和马车。

I've just started a software implementation of 32 bit floating point math. It can do about 70million additions/multiplications per second on my 2.66GHz i3. https://github.com/CodesInChaos/SoftFloat . Obviously it's still very incomplete and buggy.

这篇关于是浮点运算在C#中是否一致?这可以吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆