Класс с переопределенным методом equals, не возвращающим true для НЕКОТОРЫХ объектов, которые равны - PullRequest
0 голосов
/ 17 марта 2011

У меня есть векторный класс, у которого есть 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);
    }

Ответы [ 3 ]

2 голосов
/ 17 марта 2011

Ваша проблема должна быть ошибка округления / усечения. Это происходит постоянно с операциями с плавающей запятой, особенно с вычитанием. Когда вы проверяете на равенство, вместо a == b используйте a-b

1 голос
/ 17 марта 2011

Если вы отладите приложение, вы увидите следующее:

1.1f - 1.0f = 0.100000024

0.1 не может быть точно представлено в двоичном виде.Это все равно, что пытаться выписать 1/3 в базу 10 точно, вы не можете сделать это, потому что это продолжается вечно . Есть еще один похожий вопрос , который объясняет это и ссылается на некоторый код, чтобы распечатать, каково действительное значение с плавающей запятой

0 голосов
/ 17 марта 2011

Возможно, вы видите проблему, потому что используете поплавки. Поплавки по своей природе не точны. Если вам не нужно использовать float по какой-то причине, я бы изменил свой класс на использование десятичных.

Надеюсь, это поможет.

...