Równanie kwadratowe – sprawdzenie kodu i znalezienie błędu

2018-11-05 19:15
0

Witam. Chciałbym prosić o sprawdzenie kodu, ponieważ podobno znajduje się tam jeden błąd, którego nie potrafię zlokalizować. Z góry dziękuję :)
Edit:
Kod tutaj:

#include <iostream>
#include <conio.h>
#include <math.h>

using namespace std;

int main()
{
    double a, b, c, d, x1, x2;
    cout << "Rozwiazywanie rownania kwadratowego" << endl;
    cout << "Podaj wspolczynniki:" << endl;
    cout << "a: ";
    cin >> a;
    cout << "b: ";
    cin >> b;
    cout << "c: ";
    cin >> c;
    d = (b * b) - (4 * a * c);
    if (a != 0)
    {
        cout << "Delta wynosi: " << d << endl;
        if (d < 0)
        {
            cout << "Rownianie nie posiada rozwiazan w dziedzinie rzeczywistej.";
            _getche();
            return 0;
        }
        else if (d == 0)
        {
            x1 = -b / 2 * a;
            cout << "Rownanie posiada jedno rozwiazanie x0 = " << x1;
            _getche();
            return 0;
        }
        else
        {
            x1 = (-b - sqrt(d)) / (2 * a);
            x2 = (-b + sqrt(d)) / (2 * a);
            cout << "Rownianie posiada dwa rozwiazania: x1 = " << x1 << " x2 = " << x2;
            _getche();
            return 0;
        }
    }
    else if ((a == 0) && (b != 0))
    {
        x1 = (-c) / (2 * b);
        cout << "Wspolczynnik a = 0, dlatego jest to rownianie liniowe z rozwiazaniem x0 = " << x1;
        _getche();
        return 0;
    }
    else if((a == 0) && (b == 0))
        if (c != 0)
        {
            cout << "Rownanie sprzeczne " << c << " = 0";
            _getche();
            return 0;
        }
        else
        {
            cout << "Rownianie tozszamosciowe 0 = 0";
            _getche();
            return 0;
        }
    _getche();
    return 0;
}
edytowany 2x, ostatnio: furious programming, 2018-11-05 19:26
czy _getche(); nie należy do C++/CLI ? W C++ masz cmath zamiast math.h. poza tym po co potrzebujesz conio.h? W C++ nie zaleca się używania składni zaleznej od platformy. - GironX 2018-11-05 19:21
@GironX: na temat odpowiadaj w postach. - furious programming 2018-11-05 19:26
Kurcze, fakt. - GironX 2018-11-05 19:36
Ja bym to na dwóch zmiennych zrobił :) - Marcin.Miga 2018-11-05 21:22
@GironX: to nie jest składnia, tylko jedna funkcja. i nie ma związku z C++/CLI. jest po prostu niestandardowa. - Azarien 2018-11-05 22:02

Pozostało 580 znaków

2018-11-05 19:22
3

https://wandbox.org/permlink/c0cCJQw07e5XWM73
kompilator krzyczy, że coś jest nie tak z else,

  1. Wszystko w main, więc trudno się czyta, nie da się testować, ani użyć w innym kodzie
  2. pomieszane UI z logiką

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22, 2018-11-05 19:28
Zgubił nawiasy. - GironX 2018-11-05 19:27
ja wiem, tylko się czepiam - MarekR22 2018-11-05 19:34

Pozostało 580 znaków

2018-11-05 19:29

Chyba nawiasów tutaj brakuje:


else if((a == 0) && (b == 0))
        if (c != 0)
        {
            cout << "Rownanie sprzeczne " << c << " = 0";
            _getche();
            return 0;
        }
        else
        {
            cout << "Rownianie tozszamosciowe 0 = 0";
            _getche();
            return 0;
        }

Pozostało 580 znaków

2018-11-05 19:32
1

Dziękuję za szybką pomoc :)

Pozostało 580 znaków

2018-11-05 19:34
1

Jak się wprowadzi trudniejsze dane to nie działa:
2 4.4 2.42 (powinno być jedno rozwiązanie -1.1)
https://wandbox.org/permlink/jVE7zoRxG8SHVq1s

FYI: to wynika, ze skończonej precyzji double i że pewnych liczb zapisanych dziesiętnie nie da się zapisać binarnie (w double), tak jak 1/3 nie da się zapisać jako skończoną liczbę dziesiętną.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 3x, ostatnio: MarekR22, 2018-11-05 19:37

Pozostało 580 znaków

2018-11-05 19:48
1

Bo z floatami tak łatwo nie jest, żeby to obejśc trzeba by użyć jakiejś metody iteracyjnej liczącej z zadaną dokładnością, takie coś u siebie znalazłem:
https://gist.github.com/lion1[...]1257c5c13a5445241be1c331da0ed


iteracyjnej? Po co? Po prostu trzeba uwzględnić dokładność double i wykonać rachunek błędów. Zero iteracji, po prostu trochę więcej obliczeń. - MarekR22 2018-11-06 11:12
Marek ma rację, nie potrzebna jest metoda iteracyjna, więcej, tutaj nawet nie trzeba robić rachunku błędów, wystarczą wzory Viete'a. - enedil 2018-11-06 17:44

Pozostało 580 znaków

2018-11-06 09:30
Smutny Kot
0
      else if (d == 0)
      {

Ten kod chyba nigdy nie będzie wykonany, nawet jeśli porównasz z 0.0. Jeśli chcesz prawidłowego przerobienia tego przypadka, to zrób coś takiego: if (fabs(d) <= 1.0e-8)...

          x1 = -b / 2 * a;
          cout << "Rownanie posiada jedno rozwiazanie x0 = " << x1;

Tutaj masz błąd, chyba chodziło o -b / (2 * a), jak to jest poniżej?

edytowany 1x, ostatnio: furious programming, 2018-11-06 13:50
Używaj zakładki Podgląd zanim wyślesz źle sformatowanego posta. - furious programming 2018-11-06 13:50

Pozostało 580 znaków

2018-11-06 14:00
0

Jeszcze bardziej zakręcony przypadek brzegowy to: 1 -1.0e17 1e14
gdzie prawidłowym wynikiem jest: x1 = -0.001 x2 = -1e+17
a u ciebie wychodzi x1 = 0 x2 = 1e+17
https://wandbox.org/permlink/ZEvlyNOMZ0EO8vS3


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22, 2018-11-06 14:01

Pozostało 580 znaków

Liczba odpowiedzi na stronę

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