2010-09-16 13 views
9

Ottengo questo frammento di codice da qualcun altro. Secondo il webmaster, il codice viene scelto da The art of computer programming by KnuthDifferenza tra approssimativamente Equal ed essenzialmente Equal in L'arte della programmazione per computer

Poiché non ho una copia di quel libro, posso sapere qual è la differenza tra le due funzioni?

bool approximatelyEqual(float a, float b, float epsilon) 
{ 
    return fabs(a - b) <= ((fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon); 
} 

bool essentiallyEqual(float a, float b, float epsilon) 
{ 
    return fabs(a - b) <= ((fabs(a) > fabs(b) ? fabs(b) : fabs(a)) * epsilon); 
} 

risposta

11

Per dare un esempio:

double a = 95.1, b = 100.0; 
assert(approximatelyEqual(a, b, 0.05)); 
assert(!essentiallyEqual(a, b, 0.05)); 

Cioè, con epsilon essendo un 5%, 95,1 è approssimativamente 100, quanto rientra il margine del 5% del valore 100 (più grande). D'altra parte, 95.1 non è essenzialmente 100, poiché 100 non ha una differenza del 5% rispetto a 95.1 (valore più piccolo).

+0

Posso dire che essenzialmenteEqual avrà sempre bisogno di un valore 'più vicino 'di approssimativamente Equal? –

+0

Sì, i valori 'essentialEqual' saranno sempre" più vicini "rispetto ai valori di' approssimativamente Equal'. – palswim

+3

Pensa alle offerte del tuo negozio abituale e quali sono le percentuali. Cosa c'è di più prezioso del 33% di sconto sul prezzo o del 33% di prodotto extra gratuito? La soluzione è che dovresti preferire lo sconto del 33% in quanto equivale a un'offerta del 50% extra libera. Lo stesso accade qui, a seconda che tu prenda l'epsilon attorno al maggiore o al più piccolo dei due valori, il risultato sarà diverso. 66,6 è approssimativamente uguale a 100 con un epsilon al 33%, ma sostanzialmente uguale a un epsilon al 50%. –

9

approximatelyEqual dà se la differenza tra a e b è minore l'errore accettabile (epsilon), determinato dalla maggiore di a o b. Ciò significa che i due valori sono "abbastanza vicini" e possiamo dire che sono approssimativamente uguali.

essentiallyEqual dà se la differenza tra a e b è minore l'errore accettabile (epsilon), determinata dalla più piccola delle a o b. Ciò significa che i valori differiscono meno della differenza accettabile in qualsiasi calcolo, così che forse non sono effettivamente uguali, ma sono "sostanzialmente uguali" (dato lo epsilon).

Questo ha applicazioni in questioni in cui abbiamo dati e tassi di "errore accettabile" e così via. Questo codice fornisce solo una definizione algoritmica di questi termini.

+0

Puoi dare un esempio del mondo reale, come dovremmo scegliere tra le 2 funzioni? –

+0

'Ciò significa che i valori differiscono meno della differenza accettabile in qualsiasi calcolo' - se i valori differiscono è minore, questo significa anche' abbastanza vicino'? Quindi, cosa sarà diverso da "approssimativamente Equal"? –

+0

Ecco un [articolo medico] (http://www.pnas.org/content/95/3/811.full) che utilizza entrambi i termini. Non è necessariamente il modo di scegliere, ma è anche il modo in cui descrivi i dati. – palswim

3

La differenza è che l'uguaglianza essenziale implica un'uguaglianza approssimativa, ma non viceversa. Quindi l'uguaglianza essenziale è più forte dell'equità approssimativa.

Inoltre uguaglianza essenziale non è transitiva, ma se a è essenzialmente uguale a b, e b è essenzialmente uguale a c, quindi a è approssimativamente uguale a c (per un altro valore di epsilon).

+0

+1 per analisi transitive –