Il seguente codice in C# non funziona:Qual è il modo migliore per confrontare Double e Int?
int iValue = 0;
double dValue = 0.0;
bool isEqual = iValue.Equals(dValue);
Quindi, la domanda: qual è il modo migliore per confrontare doppio e Int?
Il seguente codice in C# non funziona:Qual è il modo migliore per confrontare Double e Int?
int iValue = 0;
double dValue = 0.0;
bool isEqual = iValue.Equals(dValue);
Quindi, la domanda: qual è il modo migliore per confrontare doppio e Int?
In realtà non è possibile confrontare i valori in virgola mobile e integrale in modo ingenuo; in particolare, dal momento che c'è il classico floating pointrepresentation challenges. Quello che possibile fare è sottrarre l'uno dall'altro e vedere se la differenza tra loro è inferiore a una certa precisione che ti interessano, in questo modo:
int iValue = 0;
double dValue = 0.0;
var diff = Math.Abs(dvalue - iValue);
if(diff < 0.0000001) // need some min threshold to compare floating points
return true; // items equal
Bisogna davvero definire da soli ciò che equality
significa per voi . Ad esempio, potresti volere che un valore in virgola mobile torni verso il numero intero più vicino, in modo che 3.999999981 sia "uguale" a 4. Oppure potresti troncare il valore, in modo che sia effettivamente 3. Tutto dipende da ciò che stai cercando di ottenere.
MODIFICA: Nota che ho scelto 0,0000001 come valore di soglia di esempio ... è necessario decidere autonomamente quale precisione è sufficiente per il confronto. Basta rendersi conto che è necessario essere entro i limiti di rappresentazione normale di double
che credo sia definito come Double.Espilon
.
Questa è una bella soluzione al problema che ho citato. Per una maggiore precisione (solo quando è necessario), utilizzare solo numeri interi, come ho suggerito nella mia risposta. –
Sarebbe meglio confrontare con il sistema epsilon costante definito (vedi qui http://msdn.microsoft.com/en-us/library/system.double.epsilon.aspx) invece di un valore codificato come 0.0000001? NB Non ho mai codificato C# (solo C++) ma presumo lo stesso principio si applica – pxb
Lo menziono nella modifica alla mia risposta. Epsilon può o non può essere una buona scelta a seconda della precisione che l'OP ha a cuore nel suo codice. – LBushkin
Questo dipende molto da quello che consideri "uguale". Se si desidera che il confronto per ritornare vero se e solo se il doppio corrisponde con precisione il valore intero (cioè non ha nessun componente frazionaria), si dovrebbe lanciare la vostra int ad un doppio per fare il confronto:
bool isEqual = (double)iValue == dValue;
Se qualcosa del genere 1,1 sarebbe considerato uguale a 1, puoi lanciare il doppio in un int (se vuoi ignorare del tutto la componente frazionaria) o arrotondare il doppio se vuoi dire 1,9 uguale a 2.
È una pessima idea per confrontare numeri interi e numeri in virgola mobile per l'uguaglianza in qualsiasi lingua. Funziona per casi molto semplici, ma dopo aver fatto qualsiasi calcolo matematico, la probabilità che il programma faccia ciò che vuoi diminuisca drasticamente.
Ha a che fare con il modo in cui i numeri in virgola mobile sono memorizzati su un sistema digitale binario.
Se si è certi di voler utilizzare questo, creare un corso per creare il proprio numero con le frazioni. utilizzare un int per mantenere l'intero numero e un altro int per mantenere la frazione.
Oggigiorno, praticamente l'unica volta uno dovrebbe essere confrontando i valori dei tipi double
eo integer
o long
di uguaglianza rigorosa è quando, per qualche motivo, uno è memorizzazione bloccato o passando quantità integrali come valori in virgola mobile e necessità successive per riconvertirli. Nella maggior parte dei casi, tale conversione può essere eseguita più facilmente, convertendo il tipo integrale in double
e quindi confrontando il risultato di tale cast. Si noti che la conversione da long
a double
può essere imprecisa se il numero non rientra nell'intervallo ± 2 . Tuttavia, nei giorni precedenti la disponibilità di 642 bit long
, double
era un pratico tipo di archiviazione per quantità di interi che erano troppo grandi per un int
32 bit, ma abbastanza piccolo da essere gestito da double
.
noti che la conversione di un long
per double
e poi facendo il confronto produrrà un risultato "uguale" se il valore nominale del double
non corrisponde esattamente al valore long
, ma rappresenta il più vicino possibile double
a tale valore. Questo comportamento ha senso se si riconosce che i tipi a virgola mobile non rappresentano in realtà un singolo valore preciso, ma piuttosto un intervallo di valori.
double val1 = 0;
double val2 = 0.0;
if((val1 - Double.Epsilon) < 0)
{
// Put your code here
}
OR
if((val2 - Double.Epsilon) < 0)
{
// Put your code here
}
dove Double.Epsilon è il valore più basso possibile per Double.
Vedere questa domanda correlata: –
Konamiman
[Qual è il modo più efficace per float e doppio confronto?] (Http: // stackoverflow.com/q/17333/995714) –