Niewłaściwe przysłanianie zmiennych

0

Witam,
W poniższym fragmencie kodu mam do czynienia z niewłaściwym przysłanianiem zmiennych w pętli (skompilowany program nie zachowuje się tak jak by można było oczekiwać na poniższym kodzie).

double re,im;
for(q=0;q<200;q++){
	im=1.0;//
	re=1.0;//

	for(n=0;n<10000;n++){
			re+=1//*
			im-=1//*

			printf("%lf\t%lf\n",im,re);// tutaj re oraz im sie inkrementuje(dekrementuje)
			                   }
			
	printf("%lf\t%lf\n",im,re);//tutaj im oraz re mają zawsze wartość z początku pętli po q, czyli 1 a w zagnieżdżonej pętli ta wartość się przecież zmienia.

                		}
 

Co ciekawe, jak usunę dwie linie oznaczone przez *, w pętli po q wyświetlają się zmienione wartości z wewnętrznej pętli.

Gdyby ktoś nie wierzył, w załączniku program oraz potrzebny do uruchomienia plik typu wav(rozszerzenie po pobraniu trzeba zmienić).
Powyższy kod jest uproszczoną wersją tego co dzieje się między 23 a 36 linią kodu programu.

0

Kłamiesz.
http://ideone.com/AF3aha
Wyświetla się wszystko poprawnie. Tam gdzie napisałeś że mają zawsze wartość z początku pętli po q, czyli 1 wyświetla sie 0 2 tak jak powinno.

0

Wiem. Program napisany od zera działa jak należy.

Ale. Coś co wrzuciłem, po skompilowaniu na moim ubuntu się tak nie zachowuje.

W tym właśnie tkwi problem.

0

No to przeanalizuj gdzie robisz błąd i tyle. Najlepiej z pomocą debugera.

0

kod między 23 a 36 linią programu w załączniku to kalka mojego pierwszego postu(z tym że w pierwszym poście jest uproszczony).
Chodzi o to że program się nie kompiluje jak należy.

0

Jeśli sie kompiluje w ogóle to znaczy że kompiluje sie jak należy. Zaręczam ci że kompilator działa bez zarzutu a błąd jest w twoim kodzie.

0

Ciekawe, bo sprawdziłem czy błąd będzie taki sam na zmiennej typu int(tuż obok moich Im i Re) i nie ma takich cyrków.
ale ja wolałbym jednak typ double...

0

To pokaż łaskawie krótki kawałekj kodu który obrazuje twój problem. Bo póki co nadal nic nie wiadomo.

0

Okej,
C++ mówi:
Jeśli w pętli zagnieżdżonej modyfikujemy zmienne re oraz im,
to przechodząc do pętli mniej zagnieżdżonej zmienne re oraz im
mają mieć wartości które zostały zmodyfikowane w pętli zagnieżdżonej.

Tak się u mnie nie dzieje.

Teraz:
W programie są tylko dwie instrukcje printf. Trzeba raz odpalić program, potem odkomentować drugiego printfa, skompilować znowu
i porównać.

Pętla zagnieżdżona powinna wypisać sumy dla q'tego indeksu tablicy.
Pętla mniej zagnieżdżona powinna wypisywać aktualną sumę. A wypisuje wartość z początku pętli.
Wartości z obu pętli się nijak do siebie mają.

W komentarzu przy instrukcjach printf jest to lepiej wyjaśnione.

 #include <stdio.h>
#include <math.h>
#define PI  3.14159265358979323846


int main(int argc, char *argv[]){
int tab[200];
int q,n;
short chunk;
double im=0.0,re=0.0;

for(q=0;q<200;q++){
		im=re=7.0;
		chunk=floor(sin(n)*10000.0);		

		for(n=0;n<10000;n++){
			re+=(double)chunk*cos(2*M_PI*(double)(n*q)/(double)10000);
			
		
			im-=(double)chunk*sin(2*M_PI*(double)(n*q)/(double)10000);
			

	/*23*/	//	printf("%lf\t%lf\n",im,re); /*do odkomentowania dla porownania wyniku*/
							/*tu wypisze wartosci wlasciwe*/
			}
			
	/*26*/		printf("%lf\t%lf\n",im,re);/*wypisuje wartosci z 13 linii pomimo ze sumy
							 nie koniecznie maja wartosc 7  */
		tab[q]=floor(sqrt(re*re+im*im));
				}
return 0;

}
0

Gadasz bzdury. Ja widzę że w ostatnim obiegu wewnętrznej pętli re oraz im zawsze sumują się do 7.
http://ideone.com/NfNSU5

i btw liczysz na początku sin(n) a n nie ma nadanej wartości...

0

to że liczę po sin (n) to zupełny przypadek który nie ma wpływu na to o co mi chodzi, chciałem po prostu wygenerować jakieś wartości.

W twoim kodzie zamień 7.0 na 0.0 w 12 linii albo na cokolwiek innego i powiedz mi że sumy zawsze będą miały wartość 0.0 ....

Nie mają prawa.

Druga opcja:
program skompilowany z opcjami wypisywania %lf ma złe wyniki
niż skompilowany z opcją %le.
Trzeba tylko zamienić i się przekonać

0

No ale ja widzę pod debugerem że jak najbardziej sumy są takie same. Tzn suma tego ciągu (double)chunk*cos(2*M_PI*(double)(n*q)/(double)10000) po n od 0 do 10000 wynosi zawsze 0, tak samo dla tego drugiego ciągu.

edit: @eliott bzudura, co ci niby zmienia to %ef? Że zamiast 0 wypisuje ci jakieś bardzo małe liczby tylko 1e-30? To jest zwykła niedokładność double. To jest takie samo 0.

0

O co mnie chodzi z %lf oraz %le .
odpal, oraz zamień wszędzie %lf na %le i odpal znowu:

  #include <stdio.h>
#include <math.h>
#define M_PI  3.14159265358979323846


int main(int argc, char *argv[]){
        int tab[200];
        int q,n =0;
        short chunk;
        double im=0.0,re=0.0;
        for(q=0;q<20;q++){
                im=re=0.0;
                chunk=floor(sin(q*q)*10.0);
                for(n=0;n<10;n++){
                    re+=(double)chunk*cos(2*M_PI*(double)(n*q)/(double)10);
                    im-=(double)chunk*sin(2*M_PI*(double)(n*q)/(double)10);
                                printf("W petli: %lf\t%lf\n",im,re);
                }
                printf("to proszę porównać  -->              %lf\t%lf\n",im,re);
                tab[q]=floor(sqrt(re*re+im*im));
        }
        return 0;
}
~                                                                                                                       
~      
0

Dobra, Mój błąd.

-2.442491e-15 w formacie wykładniczym to tyle co -0.000000 w doublu,
w dodatku w ostatnich przykładach kodów niefortunnie sumy schodziły do zera
i pomyślałem, że coś jest nie tak, a było okej.

Przepraszam za zamieszanie.

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