2012-04-06 21 views
6

Mi chiedo se esiste un modo per correggere in modo semplice e sicuro i numeri in virgola mobile.Correggere i numeri in virgola mobile

Per esempio,

Quando è entrato: "32 + 32.1" Risultato: "64,0999999999999"

Inoltre devo dire che questo accade abbastanza frequentemente quando si utilizza la notazione scientifica. "(2,3 * 10^23) * (1.452 * 10^23)" Returns: "3.339599999999999999e + 46"

E, infine, a volte il numero che viene restituito è: es. 123.0000000000001

Grazie per l'aiuto!

EDIT

La risposta che è stata approvata è grande. Ma quello che ho trovato funzionato per me era usare% g con un doppio in NSString stringWithFormat. % g sembra arrotondare tutto abbastanza appropriatamente. ex.

answer.text = [NSString [email protected]" %g ", doubleAnswer]; 

Usando doppi attraverso i vostri calcoli e quindi utilizzando il metodo che sembrava funzionare per me, e spero che questo aiuta gli altri pure. Se questa non è la risposta che stai cercando, controlla la risposta approvata!

risposta

8

I numeri in virgola mobile non rappresentano numeri specifici molto bene. Usando il doppio lo farai meno spesso ma avrai ancora il problema. Per una descrizione tecnica di come vengono memorizzati i numeri in virgola mobile (e perché abbiamo questo problema in primo luogo), vedere questo articolo di Wikipedia: IEEE 754-1985. (Fondamentalmente, i float sono memorizzati come una rappresentazione binaria del valore e hanno solo tanti bit da utilizzare, quindi si esauriscono rapidamente e devono arrotondare al valore più vicino che sono in grado di rappresentare.)

In genere non si Non preoccupatevi del +/- .0000001 e semplicemente formattateli quando volete visualizzarli all'utente con il numero appropriato di punti decimali e verrà arrotondato. Anche se internamente non importa come viene memorizzato.

Per esempio, se si desidera visualizzare il "risultato" si può fare qualcosa di simile:

float myFloat = 32 + 32.1; 
NSString *result = [NSString stringWithFormat:%@"%.2f", myFloat]; 
// result will contain 64.10 

Se non si desidera un numero fisso di punti decimali, è anche possibile utilizzare il galleggiante per stringa di capacità di conversione di NSNumber:

float myFloat = 32 + 32.1; 
NSNumber *myNumber = [NSNumber numberWithFloat:myFloat]; 
NSString *result = [myNumber stringValue]; 
// result will contain 64.1 

NSDecimalNumber si prenderà cura di tutto questo per voi, ma un po 'più coinvolto e coinvolge più in alto, ma ecco un esempio per iniziare:

NSDecimalNumber *num1 = [NSDecimalNumber decimalNumberWithString:@"32"]; 
NSDecimalNumber *num2 = [NSDecimalNumber decimalNumberWithString:@"32.1"]; 
// Or since you use exponents: 
// NSDecimalNumber *num2 = [NSDecimalNumber decimalNumberWithMantissa:321 exponent:-1 isNegative:NO]; 

NSDecimalNumber *myNumber = [num1 decimalNumberByAdding:num2]; 
NSString *result = [myNumber stringValue]; 
// result will contain 64.1 
+1

ahh vero vero, ma se volessi visualizzarlo come 62.1, ma comunque lasciare la possibilità di visualizzare 64.1065 per esempio (questo è quello che sto cercando btw, grazie.) –

+1

Poi hai bisogno di traccia i decimali che vuoi mostrare (disordinati) o non usare float e passare a un altro tipo di variabile (probabilmente 'NSDecimalNumber'). – lnafziger

+1

Ci proverò. –

2

Non è possibile "correggere" un numero in virgola mobile perché i numeri in virgola mobile semplicemente non possono rappresentare il numero desiderato.

I numeri in virgola mobile sono notevolmente imprecisi e, in generale, non devono essere utilizzati per operazioni che implicano molti calcoli poiché l'errore cumulativo è spesso catastroficamente negativo.

Utilizzare invece double. Possono rappresentare un intervallo di valori molto più ampio e, di conseguenza, possono rappresentare molti più valori in modo abbastanza preciso. Se ciò non è abbastanza buono, dovrai passare a qualcosa con maggiore precisione. Forse NSDecimalNumber.

Problemi correlati