从Unity的
文档来看,
==
返回“对于非常接近相等的向量为真”。然而,当Vector以负无穷大的x、y、z初始化时,这种实现会产生问题。
让我们看一下如何为
Vector3
定义
==
:
public static bool operator == (Vector3 lhs, Vector3 rhs) {
return Vector3.SqrMagnitude (lhs - rhs) < 9.999999E-11;
}
在执行
SqrMagnitude
之前,会先执行
lhs - rhs
,因此让我们看一下
-
的定义:
public static Vector3 operator - (Vector3 a, Vector3 b) {
return new Vector3 (a.x - b.x, a.y - b.y, a.z - b.z);
}
对于普通数字,这是可以的,但是由于a.x、b.x等都是Mathf.NegativeInfinity
,减法的结果将会是NaN
。现在当它执行sqrMagnitude
时:
public float sqrMagnitude {
get {
return this.x * this.x + this.y * this.y + this.z * this.z;
}
}
这也会返回
NaN
。
从
文档中,我们注意到以下内容:
- 如果任一操作数为NaN,则对于除!=外的所有运算符,结果均为false;对于!=,结果为true。
因此,当我们回到这段代码时:
return Vector3.SqrMagnitude (lhs - rhs) < 9.999999E-11;
简化后的代码为return NaN < 9.999999E-11;
,根据文档所述将返回False
。
Debug.Log(Mathf.Mathf.NegativeInfinity == Mathf.Mathf.NegativeInfinity)
的行为符合预期的原因在这里有说明。
- 负零和正零被认为是相等的。
- 负无穷小被认为比所有其他值都小,但与另一个负无穷小相等。
- 正无穷大被认为比所有其他值都大,但与另一个正无穷大相等。
==
运算符内部。 - GSerg