Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

problem z kompilacja

Ostatnio zmodyfikowano 2008-12-01 19:54
Autor Wiadomość
emdzej
Temat założony przez niniejszego użytkownika
problem z kompilacja
» 2008-11-29 18:46:59
program zle liczy mi arctg nie moge znalezc bledu z gory wielkie dzieki za pomoc

Tu jest polecenie do programu: http://www.konto4.mordy.pl/zadanie.jpg

a tu kod:

C/C++
#include <stdio.h>
#include <math.h>
#include <ctype.h>  /*aby moc używać funkcji isdigit*/
#include <stdlib.h> /*dla funkcji atof*/


#define ATAN_MAX 1   /*maksymalna wartosć x z której można w tym programie policzyć sh*/
#define ATAN_MIN -1  /*minimalna wartosć x z której można w tym programie policzyć sh*/

#define MIN_KROK 0.0001  /*minimalna wartosć kroku*/
#define MAX_KROK 2       /*maksymalna wartosć kroku*/

#define MIN_DOKLADNOSC 0.0001  /*minimalna dokładnosć*/
#define MAX_DOKLADNOSC 99.01   /*maksymalna dokładnosć*/

#define KEY_BUF_SIZE 100  /*rozmiar bufora wykorzystywanego do wczytywania liczb*/

#define EPSILON 0.1 /*wartosć używana do porównywania liczb zmiennopozycyjnych*/

#define BLADP 0.273239 /*Maksymalna wartosc bledu*/
#define WART_ATAN 0.785398   /*Wartosc arc tg dla x=1 => y=PI/4*/

#define KROPKA '.'
#define MINUS  '-'
#define ENTER '\n'
#define ZERO 0

double wczytaj_wartosc( const char str[], double min, double max )
{
    char bufor[ KEY_BUF_SIZE ]; /* bufor na dane z klawiatury*/
    double wynik; /*zmienna w ktorej bedzie zwracany w wynik*/
    int i = 0; /*zmienna iteracyjna*/
    int ok =- 1; /*zmienna okreslajaca ostateczna poprawnosc liczby */
    int bad_num; /*zmienna okreslajaca poprawnosc danych w buforze klawiatury*/
    int ilosc_kropek; /*ilosc kropek w buforze klawaitury - zabezpieczenie przed podawaniem niepoprawnych liczb z kilkoma znakami*/
   
    while( ok != 1 ) /*wykonuj petle dopoki wczytana liczba nie bedzie prawidlowa*/
    {
        bad_num = 0; /*zeruj flagi bledu*/
        ilosc_kropek = 0;
       
        for( i = 0; i < KEY_BUF_SIZE; i++ ) /*zeruj bufor klawiatury*/
             bufor[ i ] = 0;
       
        printf( "%s", str ); /*wyswietl informacje dla uzytkownika przekazane w argumentach funkcji*/
        fflush( stdin ); /*wyczysc strumien wejscia*/
        fgets( bufor, KEY_BUF_SIZE, stdin ); /*wczytaj pierwsze 100 znakow z wejscia do tablicy bufor*/
       
        for( i = 0; i < KEY_BUF_SIZE; i++ ) /*trzeba sprawdzic jakie elemaenty zawiera lancuch aby nie bylo problemow przy konwetacji na double*/
        {
            if( isdigit( bufor[ i ] ) == 0 ) /*jesli element lancucha nie jest cyfra to:*/
            {
                switch( bufor[ i ] ) /*badaj wartosć poszczególnych czesci bufora*/
                {
                case KROPKA: /*jesli jest to kropka*/
                    if( i == 0 ) /*i znajduje sie ona na poczatku liczby to oznacz to wartosc jaka bledna*/
                         bad_num = 1;
                    else if( bufor[ i + 1 ] == ENTER ) bad_num = 1;
                    else /*jesli kropka znajduje sie w innym miejscu to zwieksz tylko licznik kropek*/
                         ilosc_kropek++;
                   
                    break;
                case ZERO: /*jesli wartosc bufor[i] =0 tzn miejsca puste w buforze nie trzeba na nie reagowac,chyba ze caly string jest 0*/
                    if( i == 0 )
                         bad_num = 1;
                   
                    break;
                case ENTER: /*nie trzeba rowniez reagowac na znak nowego wiersza chyba ze jest on na poczatku -pusty string*/
                    if( i == 0 )
                         bad_num = 1;
                   
                    break;
                case MINUS: /*jesli bufor[i] to minus*/
                    if( i != 0 ) /*i nie znajduje sie on na poczatku*/
                         bad_num = 1; /*to oznacz dane wejsciowe jako bledne*/
                   
                    if( bufor[ i + 1 ] == KROPKA ) /*jesli znakiem nastepujacym po minusie jest kropka to ta liczba jest niepoprawna*/
                         bad_num = 1;
                   
                    if( bufor[ i + 1 ] == ENTER ) /*jesli zlosliwy uzytkownik podal tylko znak to oznacz liczbe jako bledna*/
                         bad_num = 1;
                   
                    break;
                    default: /*w przypadku kazdego inneo znaku nieliczbowego oznacz dane wejsciowe jako bledne*/
                    bad_num = 1;
                }
            }
        }
       
        if( ilosc_kropek > 1 ) /*jesli ilosc kropek jest wiesza od 1 to oznacz dane wejsciowe jako bledne*/
             bad_num = 1;
       
        if( bad_num == 1 )
        {
            puts( "Wprowadziles bledne dane!" );
            continue; /*jesli dane sa błędne to przejdz do początku pętli*/
        }
       
        wynik =( double ) atof( bufor ); /*zamien wartosc w buforze na liczbe typu double*/
       
        if(( wynik <= min ) ||( wynik > max ) ) { /*sprawdz czy wczytana wartosc nie wykracza poza przedzial ograniczajacy*/
            puts( ">>Podana wartosc wykracza poza zakres przyjmowanych liczb." );
            continue; /*jesli dane są błędne to przejdz do początku pętli*/
        }
       
        ok = 1; /*jesli liczba jest prawidlowa to ustaw ok na 1 i zakoncz petle*/
    }
    return wynik; /*zwrot wyniku*/
}


int atan_przyblizone( double dokladnosc )
{
    int wynik = 0; /*w tej zmiennej zostanie zwrócony wynik*/
    double blad =( 1 -( dokladnosc / 100 ) ); /*oblicz maksymalny blad wyniku*/
    int i = 0; /*zmienna iteracyjna*/
    double w_blad = BLADP; /*Nadanie zmiennej maksymalnego poczatkowego bledu*/
    double wart_szeregu = 0;
   
    while( blad >= w_blad ) /* jeżeli dany blad przez użytkownika jest wiekszy od bledu przy n-krokach w szeregu, przerwij petle*/
    {
        ++i;
        wart_szeregu += fabs(( pow( - 1, i ) /(( 2 * i ) + 1 ) ) ); /*oblicza wartosc szeregu dla x=1*/
        w_blad =(( fabs( wart_szeregu - WART_ATAN ) ) / WART_ATAN ); /*oblicza blad wzgledny w x=1*/
    }
    wynik = i;
    return wynik; /*zwroc ile wyrazow ciagu trygonometrycznego ma policzyc program dla danej dokladnosci*/
}


double policz_atan_z_szeregu( double x, double dokladnosc )
{
    double wynik = 0; /*zmienna w której zostanie zwrócony wynik*/
    double wartosc_x = x; /*zmienna zastępujaca x będzie modyfikowana*/
    int i = 0; /*zmienna iteracyjna*/
    int ilosc_krokow;
    ilosc_krokow = atan_przyblizone( dokladnosc ); /*zmiennej jest przypisywana liczba krokow liczenia wartosci ciagu, dla danej dokladnosci */
    for( i; i <= ilosc_krokow; i++ ) /* pętla wykonuje się tyle razy ile ilosc_krokow+1*/
    {
        wynik +=(( pow( - 1, i ) ) /( 2 * i + 1 ) ) /( pow( wartosc_x, 2 * i + 1 ) ); /*kolejne kroki rozwinięcia w szereg*/
    }
    return wynik; /*zwróć ostateczna wartosć arc tg z x*/
}



void policz_przedzial( double x_poczatkowy, double x_koncowy, double krok, double dokladnosc )
{
    double ilosc_iteracji =( fabs( x_poczatkowy - x_koncowy ) ) / krok; /*na poczatku trzeba wyznaczyc ilosc iteracji jakie program bedzie musial wykonac*/
    /*aby policzyc arctg z wszystkich wartosci podanych w przedziale*/
    double krok_war = 0;
    int max_iter =( int ) floor( ilosc_iteracji ); /*maksymalna wartosc iteracji zaokraglamy w dol*/
    int i = 0; /*zmienna iteracyjna*/
   
    if( x_poczatkowy - x_koncowy == 0 ) max_iter = 0;
   
    /*Tutaj znajduje sie kod odpowiedzialny za wyswietlenie tabelki wartosci x i arctgx*/
    printf( "\n Wartosc X\t Wartosc Funkcji arctg(x)\n" );
   
    for( i; i <= max_iter; i++ ) /* wykonuj sie dopoki nie obliczysz wartosci dla calego przedzialu*/
    {
        printf( " %f\t %f\n", x_poczatkowy + krok_war, policz_atan_z_szeregu( x_poczatkowy + krok_war, dokladnosc ) ); /*wyswietl po kolei wszystkie argumenty x i wartosc arctg(x)*/
        krok_war += krok; /*oblicz kolejna sume krokow*/
    }
}







int main()
{
    double x_poczatkowy, x_koncowy, krok, dokladnosc; /*wartosci podawane przez uzytkownika przy starcie programu*/
    double temp; /*zmienna pomocnicza*/
    char flaga = 't'; /*dopoki nie zmieni sie na n program bedzie sie wykonywal*/
   
    puts( "\n\nMichał Rowicki\n" );
    puts( "Program do obliczania wartosci arcusa tangensa w podanym przedziale." );
    puts( "Uwaga: im wyzszy procent dokladnosci tym precyzyjniej podany zostanie wynik." );
    puts( "Program zczytuje wszelkie znaki np.: spacje,ctr-e i nie dopuszcza ich stosowania podczas wprowadzania danych" );
    puts( "Program przyjmuje liczby jedynie w postaci dziesietnej innych nie rozpozna. Liczby wymierne nalezy podawac oddzielajac je kropka\n\n" );
   
    while( flaga != 'n' ) /*zapetl program do czasu az uzytkowinik zadecyduje o jego zakonczeniu*/
    {
        x_poczatkowy = wczytaj_wartosc( "Podaj wartosc x poczatkowego z przedzialu (-1;1>: ", ATAN_MIN, ATAN_MAX );
        x_koncowy = wczytaj_wartosc( "Podaj wartosc x koncowego z przedzialu (-1;1>: ", ATAN_MIN, ATAN_MAX );
       
        if( x_poczatkowy > x_koncowy ) /*jesli wartosc x_poczatkowego jest wieksza od x_koncowego to zamien te wartosci*/
        {
            temp = x_poczatkowy;
            x_poczatkowy = x_koncowy;
            x_koncowy = temp;
        }
        krok = wczytaj_wartosc( "Podaj krok z przedzialu: (0.0001;2>: ", MIN_KROK, MAX_KROK );
       
        if( krok >( x_koncowy - x_poczatkowy ) ) /*jesli krok jest zbyt duzy i przekraczylby wartosc zakresu to zmniejsz go do maksymalnego mozliwego*/
        {
            krok = x_koncowy - x_poczatkowy;
            printf( "Podany krok jest zbyt duzy i zostanie zmniejszony do maksymalnego mozliwego:\n>>%f\n", krok );
        }
       
       
        dokladnosc = wczytaj_wartosc( "Podaj dokladnosc obliczen z przedzialu: (0.0001;99>: ", MIN_DOKLADNOSC, MAX_DOKLADNOSC );
        policz_przedzial( x_poczatkowy, x_koncowy, krok, dokladnosc ); /*liczy i wyswietla wartosc sh dla podanego przsedzialu*/
       
        flaga = 'x'; /*ustaw flage na wartosc inna od 't' i 'n' inaczej ponizsza petla nie ma sensu*/
        while( flaga != 't' && flaga != 'n' ) /*pobieraj literki do czasu podania 't' lub 'n'*/
        {
            printf( "\nCzy chcesz wyjsc z programu? ['t'=tak/'n'=nie]: " );
            scanf( "%c", & flaga );
            fflush( stdin ); /*wyczysc bufor klawiatury inaczej napis w printf bedzie pojawial sie 2x*/
        }
        printf( "\n\n" );
    }
    return 0;
}
P-2662
lynx
» 2008-11-29 22:54:00
Popraw ten post tam gdzie jest kod na : [ code src="C++"]...kod...[/code]

/edit1:
Sorry że bawię się moderatora, ale taki kod jest ciężko zrozumieć, i brzydko wygląda.
P-2669
EdekMaestro
» 2008-12-01 19:54:13
Witam,

Jeden znaczek a takie problemy :)

Bylo:
wynik +=(( pow( - 1, i ) ) /( 2 * i + 1 ) ) /( pow( wartosc_x, 2 * i + 1 ) );

Powinno byc:
wynik +=(( pow( - 1, i ) ) /( 2 * i + 1 ) ) *( pow( wartosc_x, 2 * i + 1 ) );

Pozdr.
P-2682
« 1 »
  Strona 1 z 1