PROBLEMA C++: Float ingannevoli

Andretti60

Utente Èlite
6,440
5,091
E' lo stesso problema.
I vari tipi integer NON hanno cifre decimali, quindi quando assegni il valore di un double a un intero perdi le cifre decimali (a meno che non arrotondi al valore intero piu' vicino, per esempio 1.9 diventera' un 2).
Uno dei tanti motivi per cui e' sempre consigliato di usare sempre variabili double per fare operazioni matematiche, e arrotondare solo alla fine nel caso ci sia bisogno. Vale anche per numeri che sappiamo essere solo interi in quanto le operazioni su interi possono causare overflow molto prima di quelli double.
 

Andretti60

Utente Èlite
6,440
5,091
Devi imparare a castare. Double non è un Int. Non puoi assegnare ad un int un double e viceversa.
...
Inoltre 100 non è un double, va scritto come 100.0.
Anche con la operazione esplicita di casting si avrebbe lo stesso errore, in quanto passando da un double a un int si perde risoluzione; assegnando a un double un int non si perde nulla.

Vero che 100 e 100.0 sono diversi, ma in questo caso non cambia proprio nulla in quanto quando si mischiano variabili di diverso tipo in una stessa espressione il compilatore C automaticamente converte tutti al tipo piu' alto. Nel caso in questione
Codice:
    c *= 100;
poiche' la variabile c e' un double, atomaticamente 100 viene convertito in un double.

Proprio per questi motivi i piu' recenti dialetti C (tipo C#) NON eseguono nessun cast automatico, siamo noi che li dobbiamo specificare.
 
  • Mi piace
Reazioni: BAT

_Achille

Utente Èlite
3,067
725
CPU
Intel i5-6600K @4.6 GHz
Dissipatore
Cryorig H5
Scheda Madre
ASRock Z170 Extreme 6
HDD
WesternDigital 1TB & Crucial MX200 250GB
RAM
Corsair Ven 16GB DDR4 2133MHz
GPU
Sapphire RX 580 Nitro+
Monitor
Dell S2418H
PSU
RM550X
Case
NZXT S340
Periferiche
Anne Pro 2, Razer Abyssus
OS
Windows 10 Pro
Anche con la operazione esplicita di casting si avrebbe lo stesso errore, in quanto passando da un double a un int si perde risoluzione; assegnando a un double un int non si perde nulla.

Vero che 100 e 100.0 sono diversi, ma in questo caso non cambia proprio nulla in quanto quando si mischiano variabili di diverso tipo in una stessa espressione il compilatore C automaticamente converte tutti al tipo piu' alto. Nel caso in questione
Codice:
    c *= 100;
poiche' la variabile c e' un double, atomaticamente 100 viene convertito in un double.

Proprio per questi motivi i piu' recenti dialetti C (tipo C#) NON eseguono nessun cast automatico, siamo noi che li dobbiamo specificare.
È proprio quello il punto. Bisogna specificare cosa si vuole attraverso il casting
 

Andretti60

Utente Èlite
6,440
5,091
È proprio quello il punto. Bisogna specificare cosa si vuole attraverso il casting
Certo, nel senso che quando si e' "costretti" a fare il casting ci si dovrebbe rendere conto che si sta perdendo precisione e quindi occorre usare variabili di tipo giusto. Cosa che molte volte non si capisce quando il casting e' automatico (o magari ci si e' distratti e per sbaglio abbiamo dichiarato una variabile di tipo sbagliato). Comunque il casting NON risolve i problemi di troncamento.
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,662
11,445
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
In ogni caso, casting o meno, quando hai a che fare con espressioni matematiche che mischiano valori di tipo diverso, bisogna fare attenzione...
occhi al seguente codice:
C++:
int a = 10, b = 3;
double c = a / b;
cout << "\na=" << a << "   b=" << b << endl;
cout << "\nc = " << a/b << endl; // 3 --> ERRATO
a e b sono di tipo int per cui viene effettuata la divisione tra interi ed in risultato c è 3 anche se c è di tipo double;
per avere il risultato corretto devi inserire
C++:
cout << "\nc = " << (a*1.0)/b << endl; // 3.33333
oppure
C++:
cout << "\nc = " << a/(b/1.0) << endl; // 3.33333
moltiplicando a oppure b per 1.0 (che è un double) in modo che la divisione venga effettuata tra double perché il compilatore esegue il casting automatico di cui ti parlava @Andretti60
 
  • Mi piace
Reazioni: Andretti60

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!