【问题标题】:Is it safe to compare two floored doubles using the equality operator?使用相等运算符比较两个下限双打是否安全?
【发布时间】:2011-07-07 11:50:40
【问题描述】:

我知道您永远不应该在 .NET 中使用 == 相等运算符比较浮点值,但是如果使用 Math.Floor 对两个数字进行取底,这样做是否安全?

我正在使用映射程序,并且地图块存储在不同的“区域”文件中。我可以通过将世界坐标除以 16 并将结果取底来确定要检索的区域,这得到了我的区域坐标。

我实质上是在询问是否会使用 == 运算符将具有相同整数部分(例如 4.3 和 4.8)的两个值进行比较。

【问题讨论】:

标签: c# .net floating-point equality


【解决方案1】:

浮点比较的一般问题是它们很容易产生舍入误差。当您取1.2 之类的值(不能完全 表示为小数)时,将其乘以100 并将其与120 进行比较是否相等。建议始终像这样比较差异:

var a = 1.2;
a *= 100;

if (a - 120 < 0.0001)
{
}

然而,Math.Floor 操作总是产生一个整数值。也就是说,任何小数值都会被截断,而精确整数值会被留下。

所以,如果你的语义真的是使用地板,你是安全的。

但是,如果您真的要进行舍入,请改用 Math.Round()。

【讨论】:

    【解决方案2】:

    嗯,这取决于你想做什么。

    这将告诉您下限值是否相等 - 但如果一个输入只是低于 2 的一点,而一个输入是 只是超过 2 的一点,那么尽管它们之间的差异可能很小,但它们会被视为不同。

    这适合您的场景吗?在某些情况下会,在某些情况下不会。

    【讨论】:

      【解决方案3】:

      我认为您的问题是基于错误的假设。在 .Net 中使用 == 比较浮点值是非常安全的。与== 和浮点值相关的唯一奇怪行为是Double.NaN 和Single.NaN 与== 进行比较时将返回false(由浮点规范规定)。

      使用Math.Floor 并没有改善这种情况。如果将任何特殊浮点值(NaN、NegativeInfinity、PositiveInfinity)传递给Math.Floor,它们将原样返回。所以通过== 的比较仍然会有奇怪的行为(Reference)

      使用Math.Floor 的主要效果是更多的浮点值将相互比较。例如7.1 和7.5 在Math.Floor 之后将相等。这本质上并没有更好,但可以在您的应用程序的上下文中,但很难说它将没有更多信息..您能否在此处提供更多详细信息以说明原因你认为== 不安全?

      【讨论】:

      • 我认为这更多是关于舍入误差,因此需要进行 epsilon 比较,而不是关于非有限值。
      猜你喜欢
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      相关资源
      最近更新 更多