为什么评价为假?

时间:2016-07-21 16:21:22

标签: c# unity3d

我有点困惑,无法解释这种行为:

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。

3 个答案:

答案 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}}:

  

负无穷大的表示(只读)。

Vector3Mathf.NegativeInfinity初始化为x,y,z组件将无法正常工作。如果您尝试打印此矢量,您将获得(-Infinity,-Infinity,-Infinity)而不是任何数字。

运行一些测试表明,float.MaxValueVector3中相应行为的最大值。

正如马蒂亚斯在关于=运算符的回答中所说。我相信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