为什么CGPointEqualToPoint只是执行(p.x == p.x&& p.y == p.y)?

时间:2013-06-14 12:08:16

标签: objective-c floating-point equality cgpoint cgfloat

因为比较浮点数是such a difficult and debated issue我很惊讶地看到CGPointEqualToPoint和其他CG比较方法只是这样做:

CG_INLINE bool
__CGPointEqualToPoint(CGPoint point1, CGPoint point2)
{
  return point1.x == point2.x && point1.y == point2.y;
}

在某些情况下,这不会导致问题吗?或者Objective-C是否与fabs,epsilon以及所有这些进行内置的浮点比较?我想知道为什么开发人员选择在这里使用直接相等测试。

1 个答案:

答案 0 :(得分:8)

比较浮点数的问题不在比较中。这是数字。

每个操作,无论是比较还是乘法或余弦,都必须独立运行:它有一些输入,它产生一些输出。它不能“知道”输入必须调整一定量,除非您将该数量作为另一个输入提供。

当您比较浮点数时,或者对它们执行任何操作时,请考虑如果数字是先前计算引入舍入错误的结果,会发生什么。您打算计算一些数学值 x y ,但您有一些近似值xy

现在考虑这个问题:如果你想计算 x + y ,但你不知道 x y < / em>因为你只有数字xy,这些数字可能不同,你怎么能找到 x + y ?你不能;是不可能的。当然,如果您知道xy大约是 x y ,您通常可以进行近似。

现在将此应用于比较。如果您想确定 x 是否等于 y ,但您不知道 x y ,因为您只有数字xy可能不同,您如何找到 x 是否等于 y ?你不能;这是不可能的。

但是,在比较的情况下,您无法进行近似。这是因为比较的导数实际上是无限的:微小的变化可能导致值的完全变化(从假到真,反之亦然)。

这只能通过专门设计每个应用程序来解决,以避免或以自己的方式处理问题。对于某些应用程序,当它们的近似值彼此接近时接受两个数字相等是可以的。对于其他应用程序,这将破坏应用程序。在某些情况下,允许数字不同的数量可能与其中一个数字成比例。在其他情况下,它可能与某些输入值或计算的其他中间值成比例。或者绝对容差可能是合适的。或者,计算允许数字不同的数量可能非常困难。

没有通用解决方案,因此没有“近似”比较浮点运算的通用例程。相反,基本操作被提供给应用程序:相等的比较恰好是相等的比较。超出这个范围是你必须专门为你的应用程序设计的。

考虑计算sqrt(x)acos(y)。当真正的数学 x 不是负数时,如果浮点错误使x小于零,或者当真正的数学<{1}}大于1时,会发生什么? em> y 会不到一个?在这些情况下,ysqrt会生成NaN或陷阱。您是否希望数学库用“近似”平方根或反余弦函数替换它们,这些函数在这些情况下提供了捏造的答案?那是行不通的。必须认识到问题存在之前调用函数,并且必须由应用程序设计者处理。