B. dziwny wynik działania x /= abs(x) (wektory dwuwymiarowe)

Odpowiedz Nowy wątek
2012-08-30 20:24
TheMaxx
0

W ramach wstępu: jestem w trakcie pisania projektu na własne zaliczenie z programowania (zostawiłem go jako element wątpliwej rozrywki na mijające wakacje). Prosty symulator punktu łażącego po planszy 2D, do łażenia używa biblioteki wektorów (x&y są w double). Problem występuje w jednej z funkcji:

Vector2D& NormalizeMath ()
{
    if(Length()==0.0)
    return *this;

    if(fabs(x)>fabs(y))
    {
        x /= fabs(x);
        y /= fabs(x);
    }
    else
    {
        x /= fabs(y);
        y /= fabs(y);
    }
    return *this;
} 

Teoretycznie zwracać powinna wektor o x i y z zakresu <-1,1>. Jaka jest szansa, że zwróci coś w rodzaju "1:56"? W praktyce około 1 na 10 przypadków. Dowód poniżej (wektory formatu "x:y", debug trace jeszcze ciepły; wyżej przed przejściem do funkcji, niżej po fakcie).

move set  t: 165:56
move nmath t: 1:56

Podczas gdy wcześniej ruszyła całkowicie normalnie:

move set  t: -34:156
move nmath t: -0.217949:1

Wszystko to w jednym uruchomieniu programu. Raz działa. Raz nie. Chyba nie może się zdecydować.

Kompilator GCC 4.7, system to okrojone Xubuntu 12.04 32b, komp Acer Aspire One D257, procesor któryś wielordzeniowy intelowski Atom.

Biję pokłony przed tym, kto zaproponuje rozwiązanie, wyjaśnienie albo jakąkolwiek alternatywę. Siedzę nad tym ostatnie kilka godzin, kompletnie nie wiem, czy winę za ten błąd zrzucić na Tuska, Kaczyńskiego czy może młodszego brata...

Tak tylko napiszę, że normalizacja to dzielenie każdej współrzędnej przez normę (długość). Zasadniczo zazwyczaj ma się na myśli normę Euklidesową. Chociaż w sumie można się uprzeć, że używasz normy maksimum. - Endrju 2012-08-30 20:35

Pozostało 580 znaków

2012-08-30 20:35
1

Błąd jest w pierwszej części. Zauważ, że najpierw dzielisz x przez fabs(x), a potem dzielisz y, ale przez x, który został zmieniony linijkę wyżej.

Wg mnie powinno to być tak:

 Vector2D& NormalizeMath ()
{
        if(Length()==0.0)
        return *this;

        if(fabs(x)>fabs(y))
        {
                y /= fabs(x);
                x /= fabs(x);
        }
        else
        {
                x /= fabs(y);
                y /= fabs(y);
        }
        return *this;
} 
edytowany 1x, ostatnio: Sparrow-hawk, 2012-08-30 20:36

Pozostało 580 znaków

2012-08-30 20:53
TheMaxx
0

Dzięki. Jak obiecałem, biję pokłony. Na swoje usprawiedliwienie mam tylko to, że przesiedziałem nad kodzeniem dobre kilkadziesiąt godzin non-stop. Myślę binarnie i mówię przez std::cout'a.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0