Domanda

Il seguente codice in C # non funziona:

int iValue = 0;
double dValue = 0.0;

bool isEqual = iValue.Equals(dValue);

Quindi, la domanda: qual è il modo migliore per confrontare Double e Int?

È stato utile?

Soluzione

Non puoi davvero confrontare i valori in virgola mobile e i valori integrali in modo ingenuo; in particolare, poiché esiste il classico virgola mobile sfide rappresentative . Quello che puoi è sottrarre l'uno dall'altro e vedere se la differenza tra loro è inferiore a una precisione che ti interessa, 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

Devi davvero definire tu stesso cosa significa uguaglianza per te. Ad esempio, potresti voler arrotondare un valore in virgola mobile verso il numero intero più vicino, in modo che 3.999999981 sia "uguale" a 4. Oppure potresti voler troncare il valore, quindi sarebbe effettivamente 3. Dipende tutto da ciò che stai cercando di ottenere.

MODIFICA: Nota che ho scelto 0,0000001 come valore soglia di esempio ... devi decidere tu stesso quale precisione è sufficiente per il confronto. Renditi conto che devi essere all'interno dei normali limiti rappresentativi di double che credo sia definito come Double.Epsilon .

Altri suggerimenti

È una cattiva idea confrontare numeri interi e numeri in virgola mobile per l'uguaglianza in qualsiasi lingua. Funziona per casi molto semplici, ma dopo aver fatto qualche matematica, la probabilità che il programma faccia quello che vuoi diminuisce drasticamente.

Ha a che fare con il modo in cui i numeri in virgola mobile sono memorizzati su un sistema binario digitale.

Se sei sicuro di voler utilizzare questo, crea una classe per creare il tuo numero con le frazioni. usa un int per mantenere il numero intero e un altro int per mantenere la frazione.

Questo dipende davvero da ciò che consideri "uguale". Se vuoi che il tuo confronto ritorni vero se e solo se il doppio corrisponde esattamente al valore intero (cioè non ha un componente frazionario), dovresti trasmettere il tuo int a un doppio per fare il confronto:

bool isEqual = (double)iValue == dValue;

Se qualcosa come 1.1 sarebbe considerato uguale a 1, puoi lanciare il doppio su un int (se vuoi ignorare del tutto il componente frazionario) o arrotondare il doppio se vuoi dire 1,9 a uguale a 2.

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.

Al giorno d'oggi, quasi l'unica volta in cui si dovrebbero confrontare i valori dei tipi double e intero o long per l'uguaglianza rigorosa è quando, per qualche motivo, si è bloccati nella memorizzazione o nel passaggio di quantità integrali come valori in virgola mobile e successivamente è necessario riconvertirle. Tale conversione può nella maggior parte dei casi essere realizzata più facilmente lanciando il tipo integrale in double , e quindi confrontando il risultato di quel cast. Tieni presente che la conversione da long a double potrebbe non essere precisa se il numero è al di fuori dell'intervallo & # 177; 2 52 . Tuttavia, nei giorni precedenti la disponibilità di long a 64 bit, double era un pratico tipo di archiviazione per quantità intere troppo grandi per un int ma abbastanza piccolo da essere gestito da double .

Nota che convertire un long in double e quindi fare il confronto produrrà un "uguale" risultato se il valore nominale del double non corrisponde esattamente al valore long , ma rappresenta il double più vicino possibile a quel valore. Questo comportamento ha senso se si riconosce che i tipi in virgola mobile non rappresentano effettivamente un singolo valore preciso, ma piuttosto un intervallo di valori.

scroll top