我有点困惑,无法解释这种行为:
Vector3 k = new Vector3(Mathf.NegativeInfinity, Mathf.NegativeInfinity,Mathf.NegativeInfinity);
Debug.Log(k==k); // evaluates to False
虽然
Debug.Log(Mathf.Mathf.NegativeInfinity == Mathf.Mathf.NegativeInfinity)
// evaluates to True as expected
我正在使用Unity版本5.3.5f1。
答案 0 :(得分:5)
来自Unity的documentation,==
返回"对于非常接近等于"的向量,则为true。但是,当使用x,y,z的负无穷大初始化Vector时,此实现会产生问题。
让我们看一下==
的{{1}}定义方式:
Vector3
在执行public static bool operator == (Vector3 lhs, Vector3 rhs) {
return Vector3.SqrMagnitude (lhs - rhs) < 9.999999E-11;
}
之前,它会先执行SqrMagnitude
,所以让我们看看如何定义lhs - rhs
:
-
这适用于普通数字,但是,因为a.x,b.x等等。是public static Vector3 operator - (Vector3 a, Vector3 b) {
return new Vector3 (a.x - b.x, a.y - b.y, a.z - b.z);
}
,减法将导致Mathf.NegativeInfinity
。现在它NaN
:
sqrMagnitude
这也将返回public float sqrMagnitude {
get {
return this.x * this.x + this.y * this.y + this.z * this.z;
}
}
。
从docs,我们注意到以下内容:
- 如果任一操作数为NaN,除了!=之外的所有操作符的结果为false,结果为真。
因此,当我们回到这段代码时:
NaN
它简化为return Vector3.SqrMagnitude (lhs - rhs) < 9.999999E-11;
,将按照文档中的说明返回return NaN < 9.999999E-11;
。
此外,False
行为符合预期的原因记录为here。
- 负和正零被视为相等。
- 负无穷大被认为小于所有其他值,但等于另一个负无穷大。
- 正无穷大被认为大于所有其他值,但等于另一个正无穷大。
答案 1 :(得分:2)
可以或不可以实施平等运营商。它只是给定类型的实现细节。或者也可以错误地实施。
即使比较两个引用时给定类的所有属性都相等,如果==
和!=
没有重载,或者它们的实现是错误的,它可能会像你的那样以意外结果结束。
例如:
public class A
{
public static operator bool ==(A left, A right) => false;
public static operator bool !=(A left, A right) => false;
}
A a = new A();
bool equals = a == a; // false
bool notEquals = a != a // false
顺便说一句:
bool referenceEquals = ReferenceEquals(a, a); // TRUE!
答案 2 :(得分:1)
由于Mathf.NegativeInfinity
不是实际数字。它只是-Infinity
的表示。根据{{3}}:
负无穷大的表示(只读)。
将Vector3
与Mathf.NegativeInfinity
初始化为x,y,z组件将无法正常工作。如果您尝试打印此矢量,您将获得(-Infinity,-Infinity,-Infinity)而不是任何数字。
运行一些测试表明,float.MaxValue
是Vector3
中相应行为的最大值。
正如马蒂亚斯在关于=
运算符的回答中所说。我相信Vector3类也是如此。使用Equals
方法也可以。
这是示例代码:
void Start ()
{
Vector3 k = new Vector3(Mathf.NegativeInfinity, Mathf.NegativeInfinity,Mathf.NegativeInfinity);
bool val = k==k;
Debug.Log("Operator on Infinity Vector3: " + val);
Debug.Log(k);
Debug.Log("Equals Method on Infinity Vector3: " + k.Equals(k));
val = (Mathf.NegativeInfinity == Mathf.NegativeInfinity);
Debug.Log("Operator on float value: " + val);
k = new Vector3(float.MaxValue, float.MaxValue,float.MaxValue);
val = k==k ;
Debug.Log("Operator on float.MaxValue: " + val);
Debug.Log(k);
Debug.Log("Equals Method on float.MaxValue: " + k.Equals(k));
}
上面的代码给出了这个结果:
Infinity Vector3上的运算符:错误
( - 无穷大, - 无限, - 无穷大)
Infinity Vector3上的等于方法:True
浮点值运算符:True
float.MaxValue上的运算符:True
(340282300000000000000000000000000000000.0, 340282300000000000000000000000000000000.0,34028230000000000000000000000000000000000.0)
Equals方法:on float.MaxValue:True