Newsgroup: it.comp.lang.c++
Titolo: Problema logico

Vi arrabbiate se vi posto un codice che si compila esatto ma ha un
problema logico che mi manda a 0 tutti i risultati??
So che il debug di un codice del genere è difficile se non si è pensato
il codice stesso, ma io non ne esco....
Ovvio, se mi dite che non ne volete sapere non lo posto nemmeno e mi
scuso subito, e torno a ricontrollare tutto....
TIA
-- 
Guru       Non coltivate i beni terreni,
               non rimarrà niente.
         Coltivate l'amore delle persone,
            vale più di qualsiasi oro. 

 scuso subito, e torno a ricontrollare tutto....
Se sono piu' di una trentina di righe di codice, si. Quello che puoi
fare e' cercare di ridurre il tuo codice a dimensioni simili
eliminando parti che ritieni funzionino e verificando via via che
l'errore permane. In questo modo e' molto probabile che troverai
l'errore da solo prima di avere un esempio adatto ad essere postato
sul newsgroup.
Buona fortuna!
Ciao,
Nicola

 sul newsgroup.
Ho usato il tuo sistema, e un primo errore (una definizione di tipo
"int" che doveva essere "float") l'ho scovato.
Ma la funzione è complessa ed è composta da due while con nel blocco di
codice un for per ogniuna, e più di così non la posso sfrondare.
Ho scritto un piccolo applicativo usando solo la funzione incriminata e
una matrice, ma mi ritrovo ancora con risultati improbabili...
Vediamo se riesco a semplificare la domanda senza postare lunghe righe
di codice.
Se ho due celle di un vettore float, e in ogniuna c'è memorizzato il
numero 0.6, se sottraggo una cella all'altra perché il risultato che ne
esce è -5.96046e-08?
Il bello è che in altre due celle con lo stesso dato memorizzato (0.6)
fatta la differenza il risultato è 1.19209e-07....


 fatta la differenza il risultato č 1.19209e-07....
Ma sei sicuro che siano 0.6 "esatti"?
Come li hai ottenuti?
Se sei nel campo del calcolo numerico, tutto cio' potrebbe essere normale.
  bye
	av.

 Se sei nel campo del calcolo numerico, tutto cio' potrebbe essere normale.
Ad esempio  (i valori sono assegnati, matrix[][] sono solo i cout della
posizione all'interno del vettore)
(matrix [3][1]= 1.7 - matrix [2][1]= 1.1) / (matrix [3][0]= 4 - matrix
[2][0]= 3)
          =    matrix [2][2]= 0.6
Per maggiore chiarezza:
(1.7-1.1)/(4-3)=0.6
l'altro 0.6 è ottenuto come:
(2.3-1.7)/(5-4)=0.6


 Ma sei sicuro che siano 0.6 "esatti"?
Merdaccia di compilatore, o di processore??
Io faccio così:
----------------------------
cout.precision (15);
  float firstarray[][6] = {
                                {1, 2, 3, 4, 5, 6},
                                {0.3, 0.6,  1.1, 1.7, 2.3, 2.9}
                           };
  printarray (firstarray, 6);
----------------------------
dove printarray è una funzione che serve a stampare il vettore a video,
e il cout della funzione suddetta è (con il cout.precision segnato)
1 0.300000011920929
2 0.600000023841858
3 1.10000002384186
4 1.70000004768372
5 2.29999995231628
6 2.90000009536743
Ma porcatr... Io gli ho detto di inserire 0.3, non 0.300000011920929...


 Ma porcatr... Io gli ho detto di inserire 0.3, non 0.300000011920929...
E alla fine sempre qui si finisce a parare. Come dovresti sapere i
computer rappresentano i numeri in forma binaria, anche quelli in
virgola mobile. Ora i soli numeri frazionabili rappresentabili
esattamente in forma binaria sono quelli che si ottengono per
combinazione lineare delle potenze negative di 2. Ad esempio
1/2 + 1/8 + 1/16
corrisponde a 0.1011 binario, ovvero 0,6875 decimale. Nessuno dei
numeri da te utilizzati risponde a queste caratteristiche, e quindi il
computer utilizza valori approssimati. Puoi migliorare
l'approssimazione usando rappresetazioni piu' ampie, come double o
long double, ma non eliminarla. Tieni presente poi che a seconda delle
operazioni che compi l'effetto di queste approssimazioni si combina e
in certi casi puo' assumere proporzioni drammatiche.
Ciao,
Nicola
P.S. Al tuo posto sceglierei un nickname meno difficile da portare ;-)

 
Ecco, hai scoperto il problema!
I numeri reali sono rappresentati in un  certo modo all'interno del 
sistema, e per dirla in parole povere non tutti i numeri reali sono 
esattamente rappresentabili. Se questo accade, viene presa la 
rappresentazione più vicina.
Nel tuo caso 0,3 che non è rappresentabile viene rappresentato da quella 
roba che hai scritto.
Se vuoi un errore più piccolo usa double anzichè float, comunque con 
numeri in virgola mobile avrai sempre un certo errore (per quanto piccolo).
Motivo per cui ad esempio è quasi sempre sbagliato confrontare due 
numeri virgola mobile con == (di solito è meglio verificare se la 
distanza tra i due numeri è minore di un certo epsilon)
Poi ci sono una miriade di altri problemi, che puoi scoprire studiando 
un po di calcolo numerico...

 Ma porcatr... Io gli ho detto di inserire 0.3, non 0.300000011920929...
Errore di arrotondamento naturale, dovuto al fatto che 0.3 non può
essere rappresentato esattamente dal computer (e non è un problema del
*tuo* compilatore o del *tuo* processore).
E' triste e avvilente che queste cose debbano essere ribadite così
spesso.
Ogni programmatore dovrebbe saperle.
Senza offesa, ma io concordo con Nicola sull'eventualità di un cambio
di nick ;-)

 P.S. Al tuo posto sceglierei un nickname meno difficile da portare ;-)
TRanquillo, non ha nulla a che vedere con le mie capacità (scarsine) al
computer, è per tutt'altro motivo... :-)
Comunque grazie!


 di nick ;-)
http://www.demauroparavia.it/50943
definizione 1a.  (anche se non sono indiano...)


 Ah, ecco... proverò usando un double....
Non elimini il problema del tutto, anche il double ha i suoi limiti.

 Non elimini il problema del tutto, anche il double ha i suoi limiti.
Infatti, nei conti un (0.6-0.5)/(4-2)= 0.0499999999999999 rimane
comunque, e poi altri, ma perlomeno qualche 0 c'è, per qualche 0.6-0.6,
e altri piccoli refusi si fanno meno sentire....
