c# - 表达式和分配的对象之间的浮点不一致

标签 c# .net floating-point

这让我很惊讶——同样的算法会根据其执行方式给出不同的结果:

> 0.1f+0.2f==0.3f
False

> var z = 0.3f;
> 0.1f+0.2f==z
True

> 0.1f+0.2f==(dynamic)0.3f
True

(在 Linqpad 中测试)

这是怎么回事?


编辑:我理解为什么浮点运算不精确,但不理解为什么它会不一致

可敬的 C 可靠地证实 0.1 + 0.2 == 0.3 对单精度 float 成立,但对 double float 不成立。

最佳答案

我强烈怀疑您可能会发现在使用和不使用调试器的情况下运行这段代码,以及在发布配置和调试配置中会得到不同的结果。

在第一个版本中,您要比较两个表达式。 C# 语言允许以比源类型更高的精度计算这些表达式。

在第二个版本中,您将加法结果分配给局部变量。 在某些情况下,这将强制将结果截断为 32 位 - 导致不同的结果。在其他情况下,CLR 或 C# 编译器会意识到它可以优化局部变量。

来自 C# 4 规范的第 4.1.6 节:

Floating point operations may be performed with higher precision than the result type of the operation. For example, some hardware architectures support an "extended" or "long double" floating point type with greater range and precision than the double type, and implicitly perform all floating point operations with the higher precision type. Only at excessive cost in performance can such hardware architectures be made to perform floating point operations with less precision. Rather than require an implementation to forfeit both performance and precision, C# allows a higher precision type to be used for all floating point operations. Other than delivering more precise results, this rarely has any measurable effects.

编辑:我没有尝试编译它,但在评论中,Chris 说第一种形式根本没有在执行时被评估。以上内容仍然适用(我稍微调整了我的措辞)——它只是将常量的计算时间从执行时间转移到了编译时间。只要它的行为方式与a 有效评估相同,对我来说似乎没问题 - 因此编译器自己的常量表达式评估也可以使用更高精度的算术。

关于c# - 表达式和分配的对象之间的浮点不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13290758/

相关文章:

python - 为什么 Python numpy float32/int 除法给出 float64 结果?

c# - 带有自定义控件的 Xamarin.Android 通知在 API26 中不起作用

c# - 有没有更好的方法来处理两个 bool 条件的组合?

c# - 如何在winform的中心设置控件?

c# - Visual Studio 2012 - 代码覆盖率 - 如何正确执行?

c++ - 如何计算信息增益的值以减少浮点逼近误差?

c - gcc 中的 printf 错误结果

c# - 将泛型数组转换为特定类型

c# - Debug.Assert/Retry,32 位和 64 位的不同行为

.net - Entity Framework CTP5 代码优先 : How do I specify the type of the discrimimator column in Table-Per-Hierarchy Mapping?