【问题标题】:Class with overridden equals method not returning true for SOME objects that are equal对于某些相等的对象,具有覆盖的 equals 方法的类不返回 true
【发布时间】:2011-07-17 02:46:52
【问题描述】:

我有一个向量类,它的 Equals(object obj) 方法被覆盖,以便我可以比较它们。

public class Vector3f
{
    public float x,y,z;
    public Vector3f(float x, float y, float z)
    {
       this.x = x;
       this.y = y;
       this.z = z;
    }

    public static Vector3f operator +(Vector3f a, Vector3f b) {
        return new Vector3f(a.x + b.x, a.y + b.y, a.z + b.z);
    }

    public static Vector3f operator -(Vector3f a, Vector3f b) {
        return new Vector3f(a.x - b.x, a.y - b.y, a.z - b.z);
    }
    public override bool Equals(object obj)
    {
        Vector3f other = (Vector3f)obj;
        return x == other.x && y == other.y && z == other.z;
    }

    public override string ToString()
    {
        return String.Format("<{0},{1},{2}>",x,y,z);
    }
}

加号运算符在我的单元测试中按预期工作。但是,当我减去两个向量时,它说它们不相等

Test 'RTTests.Testies.vector_subtraction_works' failed: 
Expected: <<1.1,0.1,0.1>>
But was:  <<1.1,0.1,0.1>>
Testies.cs(60,0): at RTTests.Testies.vector_sub_works()

我不确定为什么比较适用于加法而不是减法,尤其是因为两种情况下的输出值相同?

编辑:我对此的测试

    [Test]
    public void vector_addition_works()
    {
        Vector3f v1 = new Vector3f(1.0f, 1.0f, 1.0f);
        Vector3f v2 = new Vector3f(1.6f, 3.2f, 4.7f);

        Vector3f expected = new Vector3f(2.6f, 4.2f, 5.7f);
        Vector3f actual = v1 + v2;

        Assert.AreEqual(actual, expected);
    }

    [Test]
    public void vector_sub_works()
    {
        Vector3f v1 = new Vector3f(1.1f, 1.1f, 1.1f);
        Vector3f v2 = new Vector3f(0.0f, 1.0f, 1.0f);

        Vector3f expected = new Vector3f(1.1f, 0.1f, 0.1f);
        Vector3f actual = v1 - v2;

        Assert.AreEqual(actual, expected);
    }

【问题讨论】:

  • 或许您也应该发布失败的测试程序。
  • 我同意@Eugenio ...我认为这是浮点运算的问题。您可以尝试对加法和减法使用相同的浮点值,看看它是否会改变任一结果。不过,最后,我要么与您在下面的 epsilon 进行比较,要么将您的值移至 decimal (尽管这会增加您的班级规模,因为 float 是 32 位,而decimal 是 128)

标签: c# c#-4.0 equals-operator


【解决方案1】:

您的问题一定是舍入/截断错误。它一直发生在浮点运算中,特别是减法。当您测试相等性时,使用 a-b

【讨论】:

  • 即使是简单的数字,如 1.0f - .5f?
  • @Matt:是的。一个好的经验法则是从不对浮点数进行相等检查,仅大于或小于比较。如果您需要可靠的精度,请使用decimal
  • 这通常发生在您对它们执行了几次操作之后,但这可能取决于您的机器。您可以通过逐步调试每一行来自己测试它。您也可以分别执行等式,然后查看哪个是失败的。例如:test1=x1==x2;测试2=y1==y2;结果=test1&&test2;
  • 那么你建议使用多小的常数呢?对于我使用它们的目的,我真的不需要超过 4 个小数位。
  • 在这种情况下将其设置为 0.0001,但如果将其设置为 0.00001 会更好。尝试多一位小数。尽管如此,使用双而不是单是值得的。性能折衷小,精度提高很多。
【解决方案2】:

如果您调试应用程序,您将看到以下内容:

1.1f - 1.0f = 0.100000024

0.1 不能精确地用二进制表示。这就像试图准确地写出以 10 为底的 1/3,因为it goes on forever,你不能这样做。 There is another similar question 解释了这一点并链接到一些代码以打印出浮点的实际值是什么

【讨论】:

    【解决方案3】:

    您可能会看到问题,因为您使用的是浮点数。浮点数就其性质而言并不精确。除非您出于某种原因需要使用浮点数,否则我会将我的课程改为使用小数。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-20
      • 2020-04-10
      • 2011-09-25
      • 2014-08-11
      • 2013-10-27
      • 2020-11-06
      相关资源
      最近更新 更多