Newsgroup: it.comp.lang.c
Titolo: Curiosita' del novellino!!

Ciao a tutti volevo chiedervi di risolvere un dubbio,più che altro una
curiosità, che mi e' sorta svolgendo un esercizio dal libro.
L'  esercizio chiede di realizzare un semplice programmino per convertire
una temperatura da gradi Fahrenheit  in gradi Celsius
utilizzando la formula di conversione C=(5/9) x (F-32).
Guardate che mi e' successo:
/*Program temperature*/
#include<stdio.h>
main()
{
     float c,f;
     /*Prompt per l'inserimento della temperatura in gradi F*/
     scanf("%f", &f);
     c=(5/9)*(f-32);
     printf("Temperatura in gradi Celsius:%5.1f°\n",c);
}
Il suddetto sorgente in fase di compilazione non fa' una grinza,pero'
ho notato che in fase di esecuzione assegna sempre il valore 0.0 alla
variabile c. Le cose si risolvono e tutto funziona se cambio l'assegnazione
cosi : c=(5*(f-32))/9 oppure cosi': (5./9.)*(f-32.)
Il problema come al solito e' PERCHÉ?Perché l'  assegnazione di prima non
andava, perché il suo risultato era sempre nullo?
Scusate se rompo un po' e' che sono perfezionista e mi va' di capire un po'
come funzionano le cose in questo affascinante linguaggio C.
PS:se volete potete rispondermi pure in e-mail: 
pdig...@neomedia.it

Il primo non funziona perche' il C fa prima la divisione tra i due interi 5
e 9 il cui risultato intero e' 0 e quindi lo usa per moltiplicarlo per il
risultato dell'espressione successivo.
In parole povere il C non converte i dati fino a quando una parte
dell'espressione lo necessiti non curandosi di possibili perdite di dati.
Non sono sicuro se con il massimo livello di warning il compilatore ti
avrebbe segnalato "possible loss of data". Non credo.
Ciao.
Antonio Donatiello

     c=(5/9)*(f-32);
Come indicato dalle parentesi l'operazione da eseguire per ultima è la
moltiplicazione.
Viene valutata la divisione 5/9 che è una divisione tra interi dunque ha
valore intero 0
( 5/9 viene troncato e non arrotondato ). Questo è il primo moltiplicando.
Viene valutata la sottrazione f-32: il numero 32 viene promosso a float
perchè
il minuendo è float, il risultato è float ( o forse double... ma per questo
discorso
è ininfluente).
Finalmente dovrei eseguire la moltiplicazione, ma prima il moltiplicando 0
 risultato intero
della divisione 5/9 ) viene promosso a float 0.0
Ora si esegue la moltiplicazione che darà come risultato un float (0.0) .
Questo float verrà assegnato senza conversioni a c ché è pure float.
P.S: le promozioni standard sono più importanti di quanto se creda,
specialmente
quando si ha a che fare con float e double (sono solo tentativi di modellare
il concetto
di numero reale)
                                                            Livio
-------------------------------------------------------
        God is real, unless declared integer
-------------------------------------------------------

dell'espressione lo necessiti non curandosi di possibili perdite di dati.
Se ho capito bene tu dici che nell'espressione c=(5/9)*(f-32) il
C non fa' prima una verifica globale convertendo tutto in float(perché f lo
dichiarata tale) ma
procede da sinistra verso destra quindi 5 e 9 li prende come interi, a meno
che' non ci metta il puntino, ne fa' la divisione tra interi e mi da'
0 che considera come intero, ora prima di fare la moltiplicazione esegue
(f-32) e, considerato che uno degli operandi e' un float converte anche 32
in float, il risultato sarà un float, a questo punto
considera 0*(f-32) e siccome anche qui' uno degli operandi e' un float
converte 0 in float Giusto?
Per favore correggimi se ho perso qualche passaggio logico e soprattutto
grazie mille per le tue risposte che sono sempre celeri ed efficaci!!!

risultato dell'espressione successivo.
Esatto, cioe' 5 e 9 vengono considerati due interi, a prescindere che
la loro operazione avvenga tramite un segno di divisione "/".
Mi spiego :
Nel Pascal il compilatore ti avrebbe risolto l'espressione convertendo
il tutto in floating point, in virtu' della presenza dell'operatore
"/" (mentre per gli interi si usa DIV).
Il C invece fa una conversione in base agli operandi e non
all'operatore.
Per cui se gli operandi sono interi (come 5 e 9) allora il risultato
e' intero.
La divisione intera di 5 per 9 e' 0, e quindi tutta l'espressione,
data la moltiplicazione per 0 e' 0.
Scrivere 5. e 9. o 5.0 e 9.0 avrebbe segnalato al compilatore che
l'operazione avveniva tra float e quindi il risultato sarebbe stato
float.
Andrea
------------------------------------------------
combatti anche tu il nano scemo :
http://www.geocities.com/Hollywood/Studio/6989
------------------------------------------------