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

Warunek zerwania pętli "for"

Ostatnio zmodyfikowano 2019-02-21 18:53
Autor Wiadomość
Wini258
Temat założony przez niniejszego użytkownika
Warunek zerwania pętli "for"
» 2019-02-20 18:00:39
Witam wszystkich!

Moim zadaniem jest napisanie funkcji, która pierwiastkuje daną liczbę za pomocą wzoru Newtona-Raphsona.
Wzór ten jest wzorem na ciąg który w przypadku mojego programu ma zakończyć się gdy pierwsza cyfra znacząca będzie na 6 miejscu po przecinku, inaczej mówiąc, gdy różnica między sąsiadującymi wyrazami będzie mniejsza niż 0,000001.

Napisałem taką funkcje, która działa:

C/C++
long double sqrtt( double p ) {
    for( i = 0; i < 30; i++ ) {
        X[ 0 ] = 1;
        X[ i + 1 ] =( X[ i ] +( p / X[ i ] ) ) / 2;
    }
   
    return X[ i ];
}

Ta funkcja liczy po prostu 30 pierwszych wyrazów ciągu i podaję ostatni, jest to mało eleganckie, chciałbym żeby zakończyła się ona gdy różnica między sąsiadującymi wyrazami będzie mniejsza niż 0.000001, jednak gdy zmieniam warunek zerwania pętli na widoczny w kodzie poniżej funkcja wykonuję się raz i wynik który wyrzuca jest błędny.

C/C++
long double sqqrt( double p ) {
    for( i = 0; 0.000001 < fabs( X[ i ] - X[ i + 1 ] ); i++ ) {
        X[ 0 ] = 1;
        X[ i + 1 ] =( X[ i ] +( p / X[ i ] ) ) / 2;
    }
   
    return X[ i ];
}

Gdzie znajduję się błąd? Jest może jakiś inny analogiczny sposób by zerwać tę pętle w odpowiednim momencie?

Z góry dziękuję i pozdrawiam wszystkich!
P-174017
mateczek
» 2019-02-20 21:58:05
błędem jest prawdopodobnie zastosowanie tablicy i jej nieznany rozmiar. Do tego zadania nie potrzebujesz tablicy bo operujesz tylko na dwóch elementach
P-174018
Wini258
Temat założony przez niniejszego użytkownika
» 2019-02-20 23:04:30
Nie widzę możliwości zrobienia tego bez tablicy, mógłbyś napisać kawałek kodu albo wytłumaczyć jak miałoby to wyglądać?

Co do jej rozmiaru, jest od zdefiniowany na początku kodu poza funkcją, razem z innymi zmiennymi:
C/C++
double p, X[ 50 ]
int i;
P-174019
YooSy
» 2019-02-21 05:44:07
Masz zdefoniowaną tablicę o rozmiarze 50 i dla i == 49 masz buffer overflow. Nie tego nie zabezpieczasz.
P-174020
mateczek
» 2019-02-21 18:53:02
Ta metoda polega na tym że liczysz kolejne boki prostokąta ze wzoru na jego pole
C/C++
#include <iostream>
#include<cmath>
using namespace std;

int main()
{
    double pole = 3; //pole kwadratu
    double a = 1, b = pole / a; //boki prostokąta
   
   
    while( fabs( a - b ) > 0.0000000001 ) {
        a =( a + b ) / 2; //bok a jako średnia z obu poprzednio wyliczonych boków prostokąta
        b = pole / a; // pole = a*b => b=pole/a Bok "b" wyliczony ze wzoru na pole
    }
   
    cout << a;
   
}


Co do jej rozmiaru, jest od zdefiniowany na początku kodu poza funkcją, razem z innymi zmiennymi:
(Zmiennych globalnych staraj się unikać w takich przypadkach. ).

I to co napisał kolega. Jeśli tablica ma size=50 to przekroczyć tego nie możesz. A twoja funkcja tego nie pilnuje. Choć 50 iteracji to dość dużo jak na ten algorytm, więc błąd obliczeń, wynika z tego, że w zadaniu bierzesz do średniej wartość, którą dopiero liczysz później.
Wartość z przyszłości(przypadkową).

C/C++
for( i = 0; 0.000001 < fabs( X[ i ] - X[ i + 1 ] ); i++ ) { //tu jescze X[i+1] nie jest policzona
    X[ i + 1 ] =( X[ i ] +( p / X[ i ] ) ) / 2; //X[i+1] liczysz dopiero tutaj
P-174028
« 1 »
  Strona 1 z 1