2013-06-18 2 views
5
#include<stdio.h> 
int main() 
{ 
    float a,b; 
    a=4.375; 
    b=4.385; 

    if(a==4.375) 
     printf("YES\n"); 
    else 
     printf("NO\n"); 

    if(b==4.385) 
     printf("YES\n"); 
    else 
     printf("NO\n"); 

    return 0; 
} 

risposta di questo codice:Confronto di una variabile float al suo valore contenuto

YES 
NO 

Ho sempre pensato che se mi confronto con un float valore doppio. non si abbinerà mai ad esso. a meno che il valore sia un numero intero puro. ma qui galleggiare "a" ha 4.375 è esatto, ma "b" non

printf("%0.20f\n",a); 
printf("%0.20f\n",b); 

This prints : 

4.37500000000000000000 
4.38500022888183593750 



but if i print 

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

It prints 4.47499990463256835938 

Come è questo effetto arrotondamento sta mostrando in alcuni e non in altri.

Qualcuno può spiegarlo. come dovrebbe "NOI" giudicare quando il valore della variabile float corrisponderà a quello in esso contenuto e quando non lo è?

+1

0,375 = 3/8, Poiché 8 = 2^3, non è un problema archiviarlo in una variabile binaria – gkovacs90

+0

possibile duplicato di [output strano in confronto di float con float letterale] (http://stackoverflow.com/questions/1839422/strange-output-in-comparison-of-float-with-float-letteral) – devnull

+0

no not duplicate ..ho chiesto la differenza tra le due situazioni signore :) –

risposta

1

La conversione da frazione decimale a una frazione binaria è precisa solo se la frazione decimale può essere riassunto come frazioni binarie 0.5, 0.25, ..., ecc

Ad esempio nel caso

0,375 = 0,25 + 0,125 = 2 -2 + 2 -3

modo che possa essere rappresentata esattamente utilizzando bi frazioni

Dove non è possibile rappresentare il numero 0.385 utilizzando le frazioni binarie con precisione. Quindi numeri come 0.5, 0.25, 0.125, ..., ecc. O una combinazione di questi numeri può essere rappresentata esattamente come numeri in virgola mobile. Altri come 0.385 daranno risultati errati quando le operazioni di confronto o uguaglianza vengono eseguite su di loro.

+0

Grazie ora ho capito !! –

+0

se le cifre di precisione sono multiple di 25 allora. corrisponde a nessun altro! –

+1

Questa risposta non spiega perché '4.385' memorizzato in' a' non sia paragonabile a '4.385' letterale. Entrambe sono, come questa risposta descrive, approssimate con poteri di due. Una buona risposta dovrebbe indicare la causa effettiva della differenza: l'oggetto 'float' ha meno precisione del letterale' double', quindi non possono approssimare 4.385 ugualmente bene, ei loro valori sono diversi. –

1

I punti mobili non sono magici. Contengono un valore esatto e se lo si confronta con quello si confronterà uguale. I due problemi sono 1) Alcune operazioni non sono sempre del tutto esatte a causa di problemi di precisione. Se ne aggiungi uno a un float e poi lo sottraggo, allora aggiungendo che uno potrebbe aver causato una perdita di precisione nei bit meno significativi del valore e quando lo sottrai, non torni allo stesso valore che ti aspetti. 2) Non è possibile rappresentare esattamente ogni valore decimale nel formato binario in virgola mobile. Ad esempio, non è possibile memorizzare il valore esatto di 0,1 in un numero binario in virgola mobile esattamente nello stesso modo in cui non è possibile scrivere il valore di 1/3.0 come valore decimale esattamente, indipendentemente dal numero di cifre che si utilizzano.

Ma nel tuo caso se si memorizza un valore e confrontarlo con lo stesso valore che dovrebbero confrontare uguali in quanto faranno entrambi hanno gli stessi problemi nello stesso modo. Il tuo numero tuttavia è che non stai confrontando come con simili. 4.375 e 4.385 non sono mobili, sono doppi e vengono convertiti per essere memorizzati, quindi quando li confronti in seguito è possibile che il valore convertito non sia del tutto identico. Se scrivi 4.385f e 4.385f per utilizzare i valori float, dovresti ottenere SÌ entrambe le volte.