Domanda

  

Eventuali duplicati:
   Perché aritmetica in virgola mobile in C # imprecisi?

Ho avuto a che fare con alcuni numeri e C #, e la seguente riga di codice i risultati in un numero diverso di quanto ci si aspetterebbe:

double num = (3600.2 - 3600.0);

Mi aspettavo num di essere 0,2, tuttavia, si è rivelato essere ,1999999999998181. C'è qualche motivo per cui sta producendo una stretta, ma ancora diversi decimali?

È stato utile?

Soluzione

Questo perché double è un tipo di dati in virgola mobile.

Se si desidera una maggiore precisione si potrebbe passare ad usare decimal invece.

Il suffisso letterale decimal è m, in modo da utilizzare decimal aritmetica (e produce un risultato decimal) si potrebbe scrivere il codice come

var num = (3600.2m - 3600.0m);

Si noti che ci sono svantaggi di utilizzare un decimal. Si tratta di un tipo di dati 128 bit rispetto a 64 bit che è la dimensione di un double. Questo rende più costoso sia in termini di memoria e di elaborazione. Ha anche una gamma molto più piccolo di double.

Altri suggerimenti

C'è un motivo.

La ragione è che il modo in cui il numero è memorizzato nella memoria, nel caso del tipo a doppio dati, non consente una rappresentazione esatta del numero 3600,2. Inoltre non permette una rappresentazione esatta del numero 0.2.

0.2 presenta una rappresentazione infinita in binario. Se si desidera memorizzare in memoria o processore registri, effettuare alcuni calcoli, un numero vicino a 0,2 con rappresentazione finita viene memorizzato invece. Esso non può essere evidente se si esegue il codice come questo.

double num = (0.2 - 0.0);

Questo perché in questo caso, tutte le cifre binarie disponibili per rappresentare i numeri a doppia tipo di dati utilizzati per rappresentare la parte frazionaria del numero (c'è solo la parte frazionaria) e la precisione è maggiore. Se si memorizza il numero 3600,2 in un oggetto di tipo double, alcune cifre vengono utilizzati per rappresentare la parte intera - 3600 e c'è meno cifre che rappresentano parte frazionaria. La precisione è parte inferiore e frazionaria che è in realtà in memoria diverso da 0,2 a sufficienza, che risulta evidente dopo la conversione da double a stringa

Cambia il tipo di decimal:

decimal num = (3600.2m - 3600.0m);

Si dovrebbe anche leggere questo .

Wikipedia

Non posso spiegarlo meglio. Posso anche suggerire la lettura Ciò che ogni computer Scientist dovrebbe sapere aritmetica alla virgola mobile . O vedere le domande correlate su StackOverflow .

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