domenica 11 novembre 2012

Piccolo tutorial sul linguaggio C - le conversioni di tipo

Le specifiche del progetto del nostro termostato indicano che la funzione che dialoga con il sensore esterno fornisce la temperatura nel seguente modo:

Per ottenere la temperatura ambientale si dovrà usare la funzione dammitemperatura() che restituisce un valore intero compreso tra  -1000  e +1000 per valori di temperatura compresi tra -50 °C e +50 °C. il prototipo della funzione dammitemperatura() è il seguente:
  • int dammitemperatura();

Quindi, avremo bisogno di un frammento di codice per il calcolo della temperatura in gradi Celsius.
Che ne dite di questo:

float tInterna;
.
tInterna = dammitemperatura()/1000*50;

In questo modo, realizzeremmo la conversione da int a float che ci serve?
Intanto, cominciamo col dire che è una istruzione C legittima e che fa uso della conversione di tipo implicita tra int, a sinistra del segno =, e float, a destra del =. L'unico problema è il suo comportamento al variare dei valori assunti dalla funzione dammitemperatura(). Infatti, poiché sia questa funzione che 1000 e 50 sono di tipo int,  il compilatore utilizza l'aritmetica tra interi e alla fine fa la conversione implicita in float :(. Il risultato del rapporto dammitemperatura()/1000 è sempre zero per i valori della funzione tra -999 e +999 e vale  1 o -1 solo quando dammitemperatura() vale 1000 o -1000. In questo modo potremmo misurare con accuratezza solo le temperature di +50 e -50 °C. Abbastanza inutile come termostato. Che ne dite?
La soluzione, in questo come per moltissimi casi analoghi, è utilizzare la conversione di tipo esplicita e/o un uso accorto delle costanti numeriche.
In particolare, una possibile soluzione al nostro problema è la seguente

tInterna = dammitemperatura()/1000.0*50.0;

L'uso delle costanti double fa si che il compilatore adotti l'ritmetica tra double e "promuova" dammitemperatura() a double prima di fare i calcoli.

La conversione di tipo esplicita si indica anteponendo alla variabile da "convertire" il nome del tipo di destinazione tra parentesi tonde.
Vediamo un'altro esempio tratto da wikipedia: si hanno tre variabili di tipo double come segue:

double da = 3.3; 
double db = 3.3; 
double dc = 3.4;

e una espressione con conversione  esplicita da double a int:

int result = (int)da + (int)db + (int)dc; // Il risultato è 9

Se avessimo fatto al conversione dopo la somma:

int result = (int)(da + db + dc); // Il risultato è 10
Qual'è il risultato corretto? Non si può dire niente in generale, dipende dall'applicazione.

problemi nelle conversioni di tipo

Qualche possibile problema l'abbiamo già visto sopra, qui di seguito riportiamo un'elenco di possibili problemi di cui tenere conto quando si effettua una conversione di tipo:

  1. da long double float  -> può implicare l'arrotandamento di cifre;
  2. da double a float -> può implicare l'arrotandamento di cifre; 
  3. da float int  -> può implicare il troncamento delle cifre decimali;
  4. da long int int  -> può implicare l'eliminazione dei bit in eccesso dei bit più significativi;
  5. da int char  -> può implicare l'eliminazione dei bit in eccesso dei bit più significativi.




Nessun commento:

Posta un commento