Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Prosty program w c nie do końca działa poprawnie

A.T. 12 Paź 2010 16:03 2032 8
  • #1 12 Paź 2010 16:03
    A.T.
    Poziom 20  

    Witam
    mam za zadanie napisać program wyznaczający rozwiązanie układu równań z dwiema niewiadomymi metodą wyznaczników (wzory Cramera). Program ma umożliwiać wczytanie wartości współczynników: a11, a12, b1, a21, a22, b2.
    A następnie rozpoznać 3 przypadki:
    -1 rozwiązanie
    -brak rozw
    -nieskończenie wiele par rozw

    Napisałem ten program ale działa tylko gdy jest 1 rozwiązanie to je liczy i wyświetla, nie działają natomiast pozostałe 2 przypadki. Mógłby ktoś go sprawdzić i ewentualnie poprawić.
    Dziękuję i pozdrawiam[/code]

    Dodano po 21 [sekundy]:

    Code:
    #include <stdio.h>
    
    #include <math.h>

    float a11=0, a12=0, a21=0, a22=0, b1=0, b2=0;
    float x=0, y=0;
    float W=0, Wx=0, Wy=0;

    void main()
    {
         printf("a11*x+a12*y=b1\n");
         printf("a21*x+a22*y=b2\n");
         printf("Podaj a11:\n");
         scanf("%f", &a11);
         printf("Podaj a12:\n");
         scanf("%f", &a12);
         printf("Podaj b1:\n");
         scanf("%f", &b1);
         printf("Podaj a21:\n");
         scanf("%f", &a21);
         printf("Podaj a22:\n");
         scanf("%f", &a22);
         printf("Podaj b2:\n");
         scanf("%f", &b2);
         W=(a11*a22)-(a12*a21);
         Wx=(b1*a22)-(a12*b2);
         Wy=(a11*b2)-(b1*a21);
         if(W!=0) {
                  x=Wx/W;
                  y=Wy/W;
                  printf("Isnieje jedno rozwiazanie: (%f,%f)\n", x,y);
                  }
         if(W=0) {
                 if(Wx=0) {
                          if(Wy=0) {
                                   printf("Uklad ma nieskonczenie wiele rozwiazan!\n");
                                   }
                          }
                 
                 }
         if(W=0){
                if(Wx!=0 || Wy!=0){
                                  printf("Uklad nie ma rozwiazania-sprzecznosc!\n");
                                  }                       
                }
         system("PAUSE");
         return 0;
    }


    Dodano po 2 [minuty]:

    Równania:
    a11*x+a12*y=b1
    a21*x+a22*y=b2
    Oczywiście 11,12,1,21,22,2 jest w indeksie dolnym

    0 8
  • Pomocny post
    #2 12 Paź 2010 16:09
    Jarosx9
    Poziom 35  

    W tych operacjach porównania to nie powinno być == zamiast = czasem?
    = jest do przypisywania wartości.

    0
  • #3 12 Paź 2010 16:20
    A.T.
    Poziom 20  

    Dzięki za odpowiedź. Poprawiłem i drugi przypadek już działa, ale 3 przypadek, że układ nie ma rozwiązania - sprzeczność dalej nie działa. Kod wygląda:

    Code:
    #include <stdio.h>
    
    #include <math.h>

    float a11=0, a12=0, a21=0, a22=0, b1=0, b2=0;
    float x=0, y=0;
    float W=0, Wx=0, Wy=0;

    void main()
    {
         printf("a11*x+a12*y=b1\n");
         printf("a21*x+a22*y=b2\n");
         printf("Podaj a11:\n");
         scanf("%f", &a11);
         printf("Podaj a12:\n");
         scanf("%f", &a12);
         printf("Podaj b1:\n");
         scanf("%f", &b1);
         printf("Podaj a21:\n");
         scanf("%f", &a21);
         printf("Podaj a22:\n");
         scanf("%f", &a22);
         printf("Podaj b2:\n");
         scanf("%f", &b2);
         W=(a11*a22)-(a12*a21);
         Wx=(b1*a22)-(a12*b2);
         Wy=(a11*b2)-(b1*a21);
         if(W!=0) {
                  x=Wx/W;
                  y=Wy/W;
                  printf("Isnieje jedno rozwiazanie: (%f,%f)\n", x,y);
                  }
         if(W==0) {
                 if(Wx==0) {
                          if(Wy==0) {
                                   printf("Uklad ma nieskonczenie wiele rozwiazan!\n");
                                   }
                          }
                 
                 }
         if(W==0){
                if(Wx!=0 || Wy!=0){
                                  printf("Uklad nie ma rozwiazania-sprzecznosc!\n");
                                  }                       
                }
         system("PAUSE");
         return 0;
    }

    0
  • #4 12 Paź 2010 16:29
    Jarosx9
    Poziom 35  

    Spróbuj

    Code:
    if(Wx!=0 || (Wy!=0)){ 

    zapisać tak
    Code:
     if((Wx!=0) || (Wy!=0)){ 


    Trochę to nieoptymalnie programujesz bo spokojnie można by to w mniejszej ilości instrukcji zawrzeć używając else i &&.

    Jeśli się nie pomyliłem to coś takiego jest nieco lepsze:
    Code:

    void main()
    {
         printf("a11*x+a12*y=b1\n");
         printf("a21*x+a22*y=b2\n");
         printf("Podaj a11:\n");
         scanf("%f", &a11);
         printf("Podaj a12:\n");
         scanf("%f", &a12);
         printf("Podaj b1:\n");
         scanf("%f", &b1);
         printf("Podaj a21:\n");
         scanf("%f", &a21);
         printf("Podaj a22:\n");
         scanf("%f", &a22);
         printf("Podaj b2:\n");
         scanf("%f", &b2);
         W=(a11*a22)-(a12*a21);
         Wx=(b1*a22)-(a12*b2);
         Wy=(a11*b2)-(b1*a21);
         if(W!=0) {
                  x=Wx/W;
                  y=Wy/W;
                  printf("Isnieje jedno rozwiazanie: (%f,%f)\n", x,y);
                  }
        else
          {
                 if((Wx==0)&&(Wy==0)) printf("Uklad ma nieskonczenie wiele rozwiazan!\n");
                 else   
                   {
                       if((Wx!=0) || (Wy!=0)) printf("Uklad nie ma rozwiazania-sprzecznosc!\n");                                             
                    }

         system("PAUSE");
         return 0;
    }

    0
  • #5 12 Paź 2010 16:35
    A.T.
    Poziom 20  

    Dziękuję za odpowiedź:) Wszystko działa. A co do optymalizacji to na początku miałem dokładnie tak jak polecasz ale nie działało i uprościłem to maksymalnie jak się da. A wystarczyło napisać == zamiast =. Jeszcze raz dziękuję:)

    0
  • #6 12 Paź 2010 17:33
    azra
    Poziom 16  

    A tak już na marginesie, funkcja main() według standardu ma typ int i zwraca takąż wartość (0 - program wykonał się prawidłowo, każda inna wartość - wystąpił błąd), więc Twoje "void main()" jest nieprawidłowe. To, że Twój kompilator nie protestuje oznacza, że albo jest bardzo stary, albo niepotrzebnie pozwala na takie rzeczy. Być może powinieneś wymusić tryb zgodny ze standardem - w gcc flagi: -ansi -pedantic, dobrze też ustawić: -Wall -Wextra -Werror.

    Powinno być więc:

    Code:
    int main(void)
    lub
    Code:
    int main(int argc, char *argv[])
    (jeśli zamierzasz korzystać z tych argumentów) bo to co masz teraz nie ma za bardzo sensu - napisałeś, że funkcja main() nie zwraca żadnej wartości, a zwracasz zero. ;)

    Do funkcji system() potrzebny jest nagłówek <stdlib.h>, którego brak w Twoim kodzie.

    Dlaczego zadeklarowałeś zmienne jako globalne? Uznawane jest to za złą praktykę, choć wiadomo, że zdarzają się sytuacje, które wymuszają "brzydkie" rozwiązania, ale tutaj zdecydowanie nie ma to miejsca. ;)

    0
  • #7 12 Paź 2010 23:03
    Dr.Vee
    VIP Zasłużony dla elektroda

    Używanie operatora == dla liczb zmiennoprzecinkowych to proszenie się o kłopoty. To prawie nigdy nie działa zgodnie z intuicyjnym rozumieniem liczb zmiennoprzecinkowych...

    Pozdrawiam,
    Dr.Vee

    0
  • #8 13 Paź 2010 02:01
    McMonster
    Poziom 32  

    Dr.Vee napisał:
    Używanie operatora == dla liczb zmiennoprzecinkowych to proszenie się o kłopoty. To prawie nigdy nie działa zgodnie z intuicyjnym rozumieniem liczb zmiennoprzecinkowych...

    Pozdrawiam,
    Dr.Vee


    Mógłbyś rozwinąć tę wypowiedź? Bo nie mogę skojarzyć, o jakie kłopoty może tu chodzić, a zaciekawiło mnie to.

    0
  • #9 13 Paź 2010 09:12
    Mad.
    Poziom 18  

    Cytat:
    UWAGA: Liczb zmiennoprzecinkowych NIE WOLNO do siebie przyrównywać.

    Powód jest bardzo prosty. Skoro liczby FP są liczbami przybliżonymi, to wszelkie rachunki z ich wykorzystaniem obarczone są pewnym małym błędem wynikającym z precyzji zapisu zmiennoprzecinkowego. Przyrównywanie wyniku obliczeń do innej wartości FP może dać niewłaściwy efekt, ponieważ obie wartości mogą się od siebie różnić - chociaż z matematycznego punktu widzenia powinny być równe.
    Źródło: http://edu.i-lo.tarnow.pl/inf/utils/001_2008/0119.php


    Przykład ode mnie:
    Code:
    void main()
    
    {
        double a = 0.3;
        double b = 1-0.7;
        printf("%.18f %.18f \n", b, a);
        if (a == b)
            printf("Liczby sa rowne \n");
        else
            printf("Liczby nie sa rowne \n");
    }

    Prosty program w c nie do końca działa poprawnie

    Jak to należy poprawnie zrobić? Odp. w linku, w cytacie.

    0