2009-10-07 17 views
6

Ho appena letto una dichiarazione circa il confronto in virgola mobile valoreConfrontando i valori in virgola mobile

valori in virgola mobile non devono essere confrontati utilizzando il == o! = operatori. La maggior parte dei valori a virgola mobile non ha una rappresentazione binaria esatta e ha una precisione limitata .

Se sì, qual è il metodo migliore per confrontare due valori in virgola mobile?

+0

Puoi spiegare perché è necessario confrontarli? O sei solo curioso di quella documentazione? – rjmunro

+0

possibile duplicato di [Come dovrei fare il confronto in virgola mobile?] (Http://stackoverflow.com/questions/4915462/how-should-i-do-floating-point-comparison) – Magnus

risposta

7

I seguenti metodi di estensione possono essere utili per implementare il suggerimento di Kevin:

public static bool IsEqualTo(this double a, double b, double margin) 
{ 
    return Math.Abs(a - b) < margin; 
} 

public static bool IsEqualTo(this double a, double b) 
{ 
    return Math.Abs(a - b) < double.Epsilon; 
} 

Così ora si può solo fare:

if(x1.IsEqualTo(x2)) ... 
if(x1.IsEqualTo(x2, 0.01)) ... 

Basta cambiare il IsEqualTo ad un nome più appropriato, o si modifica il margine predefinito a qualcosa di meglio di double.Epsilon, se necessario.

3

numeri in virgola Generalmente galleggianti dovrebbero essere confrontate con un costrutto come

if(abs((x1 - x2) < 0.001)) 

La ragione per l'avvertimento che hai citato è si può avere due metodi di calcolo qualcosa, e possono essere uguali se non aveste errore di arrotondamento , ma l'errore di arrotondamento li rende leggermente diversi.

+1

usa 'abs (x1 - x2) <0,001 * x1' invece –

+0

@Alexandre: Perché? Sarebbe utile se potesse darci qualche spiegazione. – shuhalo

+1

@ user411768: questo è dovuto al "generale". In generale, si confronta la precisione relativa, non assoluta. Cosa succede se x1 e x2 sono nell'ordine di 10^-6, ma x1 è cinque volte più grande di x2? Sicuramente non vuoi che il precedente costrutto ti dica che x1 == x2. Ci sono casi in cui la precisione assoluta è giusta. Il soggetto è difficile –

2

"Il metodo migliore" dipende dalle circostanze del perché si desidera confrontare i numeri. In generale, se pensi di voler controllare se 2 numeri in virgola mobile sono uguali, stai facendo qualcosa di sbagliato.

I numeri in virgola mobile devono essere utilizzati per rappresentare valori reali, in entrambi i sensi della parola. Questo oggetto ha la stessa lunghezza di questo altro oggetto? Beh, possono avere la stessa lunghezza, ma se si ottiene un dispositivo di misurazione abbastanza buono, si può sempre trovare una differenza. Allo stesso modo, due numeri in virgola mobile non sono mai uguali, a meno che non stiano misurando la stessa cosa e siano stati elaborati esattamente allo stesso modo. Oltre a questo, è solo un errore di arrotondamento da qualche parte nel sistema.

Si potrebbe voler verificare che siano vicini, (più vicini di una certa soglia) come suggerito dalle altre risposte, ma non uguali.

Problemi correlati