PDA

View Full Version : [C++] ma sono cosi' niubbo !!


Bonfo
28-11-2006, 01:45
AIUTO!!!
:muro: :muro: :muro: :muro:

Mi sembra di essere tornato alle elementari. :bimbo:

Perche' questo fallisce??


double meanValue = 1.0/9;

double total = 0;
for(int index = 0; index < 9; index++)
{
total += meanValue;
}

if( total != 1)
{
printf("Error");
}


Mi stampa sempre Error
:muro: :muro: :muro: :muro: :muro: :muro:
:muro: :muro: :muro: :muro: :muro: :muro:

Qualche anima pia che mi fa capire come ho appena fatto a perdere 2 ore stanotte su un confronto ???? :cry: :cry: :cry:

akyra
28-11-2006, 09:11
ti faccio una domanda che forse ti stupirà: ma hai provato invece di stampare la scritta "error", a stampare il valore della variabile su cui si effettua il confronto?

...a quanto pare, anche se dai calcoli questa dovrebbe valere 1, in realtà essa contiene un valore diverso da 1.

trallallero
28-11-2006, 09:15
se stampi strada facendo il valore di total:
total: <0.111111>
total: <0.222222>
total: <0.333333>
total: <0.444444>
total: <0.555556>
total: <0.666667>
total: <0.777778>
total: <0.888889>
total: <1.000000>
Error

vedi che non é preciso. Quindi magari scrive 1 ma non é proprio 1 preciso preciso.
se ti interessa la parte intera fai:
if( (int)total != 1 )
cosí funzica :)

andbin
28-11-2006, 09:30
Perche' questo fallisce??Perché è un problema dovuto a come sono rappresentati i numeri floating-point. Con un numero finito di bit non è possibile rappresentare in modo preciso ed esatto tutti i numeri possibili. Ad esempio 8,75 può essere rappresentato in modo esatto mentre 8,8 non può esserlo.
Il risultato di tutto questo è che operazioni come quelle che hai fatto tu, non porteranno mai ad un risultato esatto e preciso, nel tuo caso 1.0.
Quando si lavora con i numeri floating point, bisogna fare molta attenzione ai test di (dis)eguaglianza.

Bonfo
28-11-2006, 15:44
ti faccio una domanda che forse ti stupirà: ma hai provato invece di stampare la scritta "error", a stampare il valore della variabile su cui si effettua il confronto?

...a quanto pare, anche se dai calcoli questa dovrebbe valere 1, in realtà essa contiene un valore diverso da 1.

Certo che lo avevo stamapato!! ... :stordita:
Il problema e' che a casa ia 1.00000 e' uguale a 1 :(

(In ogni caso hai fatto bene a chiedere :P)


Perché è un problema dovuto a come sono rappresentati i numeri floating-point. Con un numero finito di bit non è possibile rappresentare in modo preciso ed esatto tutti i numeri possibili. Ad esempio 8,75 può essere rappresentato in modo esatto mentre 8,8 non può esserlo.
Il risultato di tutto questo è che operazioni come quelle che hai fatto tu, non porteranno mai ad un risultato esatto e preciso, nel tuo caso 1.0.
Quando si lavora con i numeri floating point, bisogna fare molta attenzione ai test di (dis)eguaglianza.


Si...immaginavo che fosse quello il problema...pero' speravo che i nuovi compilatori, soprattutto quelli del C++ (sto usando MinGW e gcc), fossere un po' svegli al rigurado o che almeno fornissero alcune "utility" per fare questi confronti.
Ma poi, dovendo troncare il numero 0.9999999999999999, non diventa proprio un 1 :confused: ??? Oppure viene mantenuta l'informazione che il numero e' arrotondato??

EDIT: ma con Java e c# sti problemi mica ci sono....eppure la rappresentazione numerica sempre quella e' nei PC :D :D

andbin
28-11-2006, 15:59
EDIT: ma con Java e c# sti problemi mica ci sono....eppure la rappresentazione numerica sempre quella e' nei PC :D :DIl problema ce l'hai anche in altri linguaggi, compresi Java e C#. ;)

Prova questo codice C/C++:
double a = 2.54;
double b = 2.5;
double c = 0.04;
double d;

d = a - b;

if (d == c)
printf ("Uguale\n");
else
printf ("Diverso\n");

Prova questo codice Java:
double a = 2.54;
double b = 2.5;
double c = 0.04;
double d;

d = a - b;

if (d == c)
System.out.println ("Uguale");
else
System.out.println ("Diverso");

Entrambi i codici stampano "Diverso". Ma ... 2.54 - 2.5 non fa 0.04??? Sì ma il valore in 'd' è quasi quasi quasi uguale a quello in 'c' ma non sono esattamente precisamente uguali.

È un problema dovuto alla rappresentazione dei numeri floating-point.

Bonfo
30-11-2006, 11:26
... mmmh... mi fido ;)

Pero' ti posso assicurare che in Java non ci ho mai sbattuto contro, anche se i problemi di rappresentazione numerica li conosco e li ho incontarti, soprattutto con gl i interi ;)

Grazie.

andbin
30-11-2006, 12:07
anche se i problemi di rappresentazione numerica li conosco e li ho incontarti, soprattutto con gl i interi ;) :eek: Con gli interi??? :confused: E quali problemi di "rappresentazione" hai avuto???

Bonfo
03-12-2006, 21:19
Avevo dei loop un po' troppo grandi e mi capitava che un numero da positivo diventasse improvvismente negativo :eek: :eek:

:D :D

andbin
04-12-2006, 09:06
Avevo dei loop un po' troppo grandi e mi capitava che un numero da positivo diventasse improvvismente negativo :eek: :eek: Allora è un problema di "overflow".

Bonfo
04-12-2006, 14:02
Allora è un problema di "overflow".

Esatto, ma il motivo del cambio di segno e' la rappresentazione in complemento a due....quando a forza di sommare faccio diventare il rpimo bit = 1, tac, diventa un numero negativo.

Per quello l'ho considerato un problema di rappresentazione. ;)