Newsgroup: it.comp.lang.c
Titolo: problema assegnamento di un int a un float

Ciao,
In un programma ho assegnato un intero ad una variabile di tipo float.
Il compilatore dà: possibile perdita di dati.
Ed in effetti l'esecuzione del programma ha generato 0 anziché 83
(quest'ultimo era il valore che doveva produrre il programma)
Io mi chiedo: non doveva essere il contrario? Ossia, non dovevo avere
una possibile perdita di dati assegnando un float ad un int?
Di fatto i float possono essere pensati come i numeri con la virgola,
dunque contengono gli interi, potete darmi una mano a risolvere questo
enigma?
Grazie

Il compilatore dà: possibile perdita di dati.
Posta il codice. Ci vuole tanto?

 Il compilatore dą: possibile perdita di dati.
Puoi postare il messaggio del compilatore e la riga di codice incriminata?
E.

 Grazie
Saluti  Manlio Perillo

 Posta il codice. Ci vuole tanto?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
	float x;
	int a = 2;
	x = a;
	system("pause");
                return 0;
}
warning C4244: '=': conversione da 'int' a 'float'. Possibile perdita
di dati.

di dati.
Che compilatore stai usando? 

Ragionevole.
Mica tanto. La perdita di dati nell'assegnare un valore intero a un
float non č cosģ ragionevole. Il gcc non solleva nessun warning,
comunque.

 Che compilatore stai usando?
Microsoft Visual Studio 2008

 comunque.
#include <stdio.h>
int main() {
    unsigned int a = 4294966200;
    unsigned int b;
    float x;
    x = a;
    b = x;
    printf("a = %u, x = %f, b = %u\n", a, x, b);
    return 0;
}
$gcc -std=c99 -Wall float.c
$./a.out 
a = 4294966200, x = 4294966272.000000, b = 4294966272
Saluti  Manlio Perillo

ragionevole.
Continuo a ritenere che non sia "abbastanza ragionevole". Un intero è
rappresentabile esattamente come potenze di 2. Quindi perché dovrebbe
esserci perdita di informazione? Che mi sto perdendo?

Dici che è perché i fp vengono normalizzati?

 Dici che è perché i fp vengono normalizzati?
io direi che dipende dal fatto che la mantissa di un float ha meno bit 
di un int ( stiamo ipotizzando che tutti e due abbiano una dimensione 
totale di 32 bit )
per cui, sebbene un float abbia un range di valori possibili piu' grande 
di un int, gli interi rappesentabili 'esattamente' da un float hanno un 
range piu' piccolo ovvero fino alla 'saturazione' della mantissa
per cui il passaggio int -> float -> int non sempre restituisce lo 
stesso valore da cui la 'perdita di informazione'



Nello standard IEE 754, un float (finito) è rappresentato come:
(−1)s × c × 2^q
dove c è un intero compreso tra 0 e 2^24-1
http://en.wikipedia.org/wiki/IEEE754
http://en.wikipedia.org/wiki/IEEE_754-1985
Con il gcc su Linux, per interi i < 2 ^ 24 - 1, la conversione da float 
ad int (di un numero intero) è esatta
(semplicemente impostando c = i e q = 0, probabilmente).
Per valori maggiori, si ha perdita di precisione.
Lo standard ISO/IEC 9899:TC2 (almeno il draft in mio possesso) dice:
When a value of integer type is converted to a real floating point type, 
if the value being converted can be represented exactly in the new type, 
it is unchanged. If the value being converted is in the range of values 
that can be represented but cannot be represented exactly, the result is 
either the nearest higher or nearest lower representable value, chosen in 
an implementation-defined manner. If the value being converted is outside 
the range of values that can be represented the bahaviour is undefined.
Quindi mi sembra strano che MSVC converta il float `83` all'int `0`.
Se così fosse, significa che probabilmente imposta sempre q = 0, e 
quantizza `i` da una rappresentazione a 32 bit ad una a 24 bit, in 
violazione dello standard (?).
Strano anche il fatto che il GCC non emetta un warning.
Ciao  Manlio