Perché dovrei usare il complemento a 2 per confrontare due doppi invece di confrontare le loro differenze con un valore epsilon?

StackOverflow https://stackoverflow.com/questions/96233

  •  01-07-2019
  •  | 
  •  

Domanda

Referenziato Qui E Qui...Perché dovrei usare il complemento a due invece del metodo epsilon?Sembra che il metodo epsilon sia sufficiente per la maggior parte dei casi.


Aggiornamento: Sto puramente cercando un motivo teorico per cui dovresti usarne uno rispetto all'altro.Ho sempre utilizzato il metodo epsilon.

Qualcuno ha utilizzato con successo il confronto in complemento a 2?Perché?Perché no?

È stato utile?

Soluzione

il secondo collegamento a cui fai riferimento menziona un articolo che contiene una descrizione piuttosto lunga del problema:

http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

ma a meno che tu non stia modificando le prestazioni, resterei con epsilon in modo che le persone possano eseguire il debug del tuo codice

Altri suggerimenti

Il metodo bit potrebbe essere più veloce.Dico potrebbe perché sui processori moderni (multicore, altamente pipeline) è spesso impossibile indovinare cosa sia veramente più veloce.Codificare l'implementazione più semplice e ovviamente corretta, quindi misurare, quindi ottimizzare.

Insomma, quando si confrontano due carri di origine sconosciuta, scegliere un epsilon valido è quasi impossibile.

Per esempio:

Qual è un buon epsilon quando si confronta la distanza in miglia tra Atlanta GA, Dallas TX e qualche posto in Ohio?

Qual è un buon epsilon quando si confronta la distanza in miglia tra il mio piede sinistro, il mio piede destro e il computer sotto la mia scrivania?

MODIFICARE:

Ok, ho un discreto numero di persone che non capiscono perché non dovresti sapere qual è il tuo epsilon.

Ai vecchi tempi, ho scritto due programmi che funzionavano con NeverWinter Nights (un gioco realizzato da BioWare).Uno dei programmi ha preso un modello binario e lo ha convertito in ASCII.L'altro programma ha preso un modello ASCII e lo ha compilato in binario.Uno dei test che ho scritto è stato quello di prendere tutti i modelli binari di BioWare, decompilarli in ASCII e poi riportarli in binario.Poi ho confrontato la mia versione binaria con quella originale di BioWare.Uno dei problemi durante il confronto è stato gestire alcune leggere variazioni nei valori in virgola mobile.Quindi, invece di inventare un sacco di EPSILON diversi per ogni tipo di numero in virgola mobile (vertice, normale, ecc.), volevo usare qualcosa come questo confronto dei complimenti a due.Evitando così tutta la questione multipla degli EPSILON.

Lo stesso tipo di problema può applicarsi a qualsiasi tipo di software che elabora dati di terze parti e quindi deve convalidare i risultati con l'originale.In questi casi potresti non sapere nemmeno cosa rappresentano i valori in virgola mobile, devi solo confrontarli.Abbiamo riscontrato questo problema con il nostro software di automazione industriale.

MODIFICARE:

LOL, questo è stato votato su e giù da persone diverse.

Ridurrò il problema a questo, dati due arbitrario numeri in virgola mobile, come decidi quale epsilon usare?Non puoi.

Come puoi confrontare 1e23 e 1.0001e23 con un epsilon e confrontare comunque 1e-23 e 5.2e-23 utilizzando lo stesso epsilon?Certo, puoi fare alcuni trucchi epsilon dinamici, ma questo è il punto centrale del confronto degli interi (che NON richiede che gli interi siano esatti).

Il confronto intero è in grado di confrontare due float utilizzando un epsilon relativo alla grandezza dei numeri.

MODIFICARE

Steve, diamo un'occhiata a cosa hai detto nei commenti:

"Ma tu sai cosa significa per te l'uguaglianza...Quindi, dovresti essere in grado di trovare un epsilon appropriato".

Capovolgi questa affermazione per dire:

"Se sai cosa significa per te l'uguaglianza, allora dovresti essere in grado di trovare un epsilon appropriato."

Il punto di ciò che sto cercando di dire è che ci sono applicazioni in cui non sappiamo cosa significhi uguaglianza in senso assoluto, quindi dobbiamo ricorrere a un confronto relativo che è ciò che la versione intera sta cercando di fare.

Quando si tratta di velocità, segui queste regole:

  1. Se non sei uno sviluppatore molto esperto, non ottimizzare.
  2. Se sei uno sviluppatore esperto, non ottimizzare ancora.

Esegui il metodo più semplice.

Alex

Oskar ha ragione.Non rovinare tutto a meno che tu non abbia davvero bisogno di quella prestazione.

E tu no.Se ti fossi trovato in una situazione del genere, non avresti avuto bisogno di porre la domanda: lo sapresti già.Se pensi di farlo, allora non lo fai.I tuoi problemi di prestazioni si trovano altrove.Basta usare la versione leggibile.

L'utilizzo di qualsiasi metodo di confronto bit per bit comporterà problemi quando le frazioni sono rappresentate mediante approssimazioni.Tutti i numeri in virgola mobile con frazioni non denominate in potenze di due (1/2, 1/4, 1/8, 1/65536, ecc.) sono approssimati.Quindi, ovviamente, sono tutti numeri irrazionali.

terzo float = 1/3;float due=2.0;float un altro_due=terzo*6.0;if (due! = un altro_two) stampa ("approssimazione! n");

L'unica volta in cui il confronto bit per bit funzionerebbe è quando si derivano i numeri in virgola mobile esattamente nello stesso modo o sono rappresentazioni esatte (numeri interi, potenze frazionarie di due).Anche in questo caso, possono esserci più rappresentazioni di alcuni numeri, sebbene non l'abbia mai visto in un sistema funzionante.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top