PDA

View Full Version : [C] Dichiaro float ma assegno un numero reale..


piumone
12-09-2007, 15:28
E' un grave errore vero? Mi spiego nel programma che avevo da fare all'esame dovevo leggere un file contentente numeri reali, nella tensione ho fatto confusione ed ho assegnato ad una variabile float il numero reale letto da quel file. Come valuteranno la cosa??

cionci
12-09-2007, 15:38
C'è qualcosa che non mi torna...un float è la rappresentazione di un numero reale...cosa c'è che non va ?

Ziosilvio
12-09-2007, 15:47
Se per leggere il numero dal file hai usato fscanf(filepunt,"%f",&var) con var di tipo float, non dovrebbero esserci problemi, perché ci pensa fscanf a convertire la stringa di caratteri che rappresenta il numero, in un valore float da assegnare alla variabile.

Se però hai usato quella sintassi e var era double, allora probabilmente immagazzinerai un valore sbagliato, perché il formattatore corretto per i double è %lf e non %f, e fscanf non reinterpreta automaticamente i puntatori a float come puntatori a double.

piumone
12-09-2007, 15:53
C'è qualcosa che non mi torna...un float è la rappresentazione di un numero reale...cosa c'è che non va ?

Scusa hai ragione, pensavo di aver sbagliato invece ho fatto giusto, ne approfitto per chiederti: come si fa (in c) per vedere se un numero reale scelto a caso è divisibile per 5? if numreale%5==0 può andare?

andbin
12-09-2007, 15:57
if numreale%5==0 può andare?No, l'operatore % è utilizzabile solo con operandi di tipo intero.

Comunque te la cavi usando la funzione standard fmod().
http://cppreference.com/stdmath/fmod.html

cionci
12-09-2007, 15:58
No...quello si fa con la divisione intera.
Per il reale in teoria non lo potresti fare...ogni reale è divisibile per qualunque numero reale o intero (escluso 0).
Sicuro che non dovevi leggere un numero intero ?

cionci
12-09-2007, 15:59
Comunque te la cavi usando la funzione standard fmod().
Però fare un fmod e poi controllare se il resto è uguale a 0 è un bel rischio ;)

andbin
12-09-2007, 16:01
Però fare un fmod e poi controllare se il resto è uguale a 0 è un bel rischio ;)Perché?

cionci
12-09-2007, 16:16
Perché?
Perché ci sono i limiti di rappresentabilità...non tutti gli interi all'interno dell'intervallo di rappresentabilità sono rappresentabili su un double, ancor più su un float.

Ad esempio:

#include <stdio.h>
#include <math.h>

int main()
{
float f = 21141235;

printf("%f\n", f);

if(fmodf(f,5.0) == 0)
printf("multiplo di 5\n");

printf("%f\n", fmodf(f,5.0));

return 0;
}

Ora questo è un errore di rappresentazione macroscopico, ma possono essere anche più bassi, dopo diverse operazioni sui floating point.

piumone
12-09-2007, 16:21
Quindi per vedere se un reale è divisibile per 5 devo fare per forza l'fmod? visto che nei reali ci sono anche gli interi nel caso avessi letto per dire 25 il comando %5 sarebbe stato lecito oppure no? Mi sa di no eh.. :-(

cionci
12-09-2007, 16:23
Avresti dovuto fare:

if((int)f % 5 == 0)

ma in ogni caso se avessi letto 25.1111 ti avrebbe dato comunque 0...

andbin
12-09-2007, 16:28
Perché ci sono i limiti di rappresentabilità...non tutti gli interi all'interno dell'intervallo di rappresentabilità sono rappresentabili su un double, ancor più su un float.Sì lo so, un float ha una precisione di circa 7 digit e un double di circa 16 digit.
Se ragioniamo su questi casi al limite della precisione, il problema indubbiamente c'è, sono d'accordo. ;)

cionci
12-09-2007, 16:39
Se ragioniamo su questi casi al limite della precisione, il problema indubbiamente c'è, sono d'accordo. ;)
Però ci può essere non solo in questi casi macroscopici...ma anche dovuti all'accumulo di errori di rappresentabilità su operazioni successive. Se mi metto a fare una lunga serie di operazioni e poi alla fine arrivo ad un risultato che so dovrebbe essere multiplo di 5, è abbastanza probabile che non lo sia ;)
Basta trovarsi per la strada un numero reale non rappresentabile...

Anzi...con i float la lista di operazioni non deve essere nemmeno tanto lunga,


#include <stdio.h>
#include <math.h>

int main()
{
float f = 155.0;

f += 662.23;
f -= 662.23;

printf("%f\n", f);

if(fmodf(f,5.0) == 0)
printf("multiplo di 5\n");

printf("%f\n", fmodf(f,5.0));

return 0;
}