Ste*_*eve 37 c# floating-point
我知道浮点数具有精度,精度后的数字不可靠.
但是如果用于计算数字的等式是相同的呢?我可以假设结果也一样吗?
例如,我们有两个浮点数x和y.我们可以假设x/y机器1的结果与机器2的结果完全相同吗?IE ==比较将返回true
Jon*_*eet 46
但是如果用于计算数字的等式是相同的呢?我可以假设结果也一样吗?
不,不一定.
特别是,在某些情况下,允许JIT使用更准确的中间表示 - 例如,当您的原始数据是64位时为80位 - 而在其他情况下则不会.当满足以下任何条件时,这可能会导致看到不同的结果:
try块......)从C#5规范部分4.1.6:
可以以比操作的结果类型更高的精度执行浮点运算.例如,某些硬件体系结构支持"扩展"或"长双"浮点类型,其范围和精度比double类型更大,并使用此更高精度类型隐式执行所有浮点运算.只有在性能成本过高的情况下,才能使这种硬件架构以较低的精度执行浮点运算,而不是要求实现放弃性能和精度,C#允许更高精度的类型用于所有浮点运算.除了提供更精确的结果外,这几乎没有任何可衡量的影响.但是,在表单的表达式中
x * y / z,乘法产生的结果超出双范围,但随后的除法将临时结果带回双范围,表达式以更高范围格式计算的事实可能导致产生有限结果而不是无穷大.
Eri*_*ert 20
乔恩的回答当然是正确的.然而,没有一个答案说过如何确保浮点运算以规范保证的精度完成,而不是更多.
在以下情况下,C#会自动将任何浮点数截断回其规范的32位或64位表示:
x + y可能有x和y作为更高精度的数字然后被添加.但是(double)((double)x+(double)y)确保在数学发生之前和之后所有内容都被截断为64位精度.这些保证不是由语言规范做出的,但实现应该遵守这些规则.C#和CLR的Microsoft实现.
编写代码以确保浮点运算在C#中是可预测的但是可以完成是一件痛苦的事.请注意,这样做可能会减慢算术速度.
关于这种可怕情况的投诉应该针对英特尔,而不是微软; 他们是设计芯片的人,这使得可预测的算法变得更慢.
另请注意,这是一个经常被问到的问题.您可以考虑将其作为以下内容的副本:
为什么在由parantheses分隔和由语句分隔时,C#中的浮点精度会有所不同?
(.1f + .2f ==.3f)!=(.1f + .2f).Equals(.3f)为什么?
C#XNA Visual Studio:"发布"和"调试"模式之间的区别?
不,不是的.每个CPU的计算结果可能不同,因为浮点运算的实现可能因CPU制造商或CPU设计而异.我甚至还记得一些英特尔处理器中的浮点运算中的一个错误,这搞砸了我们的计算.
然后,在JIT编译器中如何评估代码存在差异.
坦白说,我不希望在同一代码库两个地返回同样的事情x/y在同x和y-在同一台机器上相同的过程; 它可以取决于编译器/ JIT的准确性x和y优化程度 - 如果它们以不同的方式注册,它们可以具有不同的中间精度.使用比预期更多的位(寄存器大小)完成了许多操作; 并且当它被强制降低到64位时可能会影响结果."确切时间"的选择取决于周围代码中发生的其他事情.
| 归档时间: |
|
| 查看次数: |
3157 次 |
| 最近记录: |