2011-09-07 9 views
6

Ho questo oscuro problema di arrotondamento in VBA.Problema di arrotondamento VBA

a = 61048.4599674847 
b = 154553063.208822 
c = a + b 
debug.print c 
Result: 
154614111.66879 

Ecco la domanda, perché VBA ha arrotondato la variabile c? Non ho emesso alcuna funzione di arrotondamento. Il valore che mi aspettavo era 154614111.6687894847. Anche se arrotondo o formatto una variabile da c a 15 decimali, non riesco ancora a ottenere il risultato atteso.

Qualsiasi spiegazione sarebbe apprezzata.

Edit:

ottenuto i risultati attesi utilizzando CDEC. Ho letto questo in risposta di Jonathan Allen nel Why does CLng produce different results?

Ecco il risultato alla prova:

a = cDec(61048.4599674847) 
b = cDec(154553063.208822) 
c = a + b 
?c 
154614111.6687894847 
+1

[aritmetica in virgola mobile possono dare risultati non accurati in Excel] (http://support.microsoft .com/kb/78113) – SeanC

risposta

11

Il motivo è la precission limitata che può essere memorizzato in una variabile in virgola mobile.
Per una spiegazione completa si legge il foglio Ciò che ogni scienziato informatico dovrebbe sapere dell'aritmetica a virgola mobile, di David Goldberg, pubblicato nel numero di Computing Surveys del marzo 1991.

Link to paper

In VBA predefinito flottante punto è Double che è il numero a virgola mobile IEEE 64 bit (8 byte).

C'è un altro tipo disponibile: Decimal che è un 96-bit (12 byte) interi scalati da una potenza variabile di 10
parole povere firmato, questo fornisce numeri in virgola mobile a 28 precission cifre.

da utilizzare per esempio:

a = CDec(61048.4599674847) 
b = CDec(154553063.208822) 
c = a + b 
debug.print c 
Result: 
154614111.6687894847 
+0

Grazie per il collegamento. – Grekoz

3

La sua non è oscura, ma non è necessariamente evidente.

Penso che abbiate una sorta di risposta, ma il problema di base è una delle "dimensioni" dei valori, ovvero la quantità di dati che è possibile memorizzare in una variabile di un determinato tipo.

Se (e questo è molto grezzo) contate il numero di cifre in ciascuno dei numeri nel vostro primo esempio vedrete che avete 15 così mentre l'intervallo di valori che un float (il tipo predefinito) può rappresentare è enorme la precisione è limitata a 15 cifre (sono sicuro che qualcuno sarà presente per correggerlo, farò spuntare la casella wiki ...)

Quindi quando si sommano i due numeri perde il meno significativo valori per rimanere entro la precisione ammissibile per un flusso.

Facendo un CDEC si sta convertendo a un diverso tipo di variabile (decimale) che è capace di una maggiore precisione