2011-09-07 27 views
6

Tengo este problema de redondeo oscuro en VBA.VBA problema de redondeo

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

Aquí está la pregunta, ¿por qué VBA redondeó la variable c? No emití ninguna función de redondeo. El valor que esperaba era 154614111.6687894847. Incluso si redondeo o formato variables c a 15 lugares decimales, aún no obtengo el resultado esperado.

Cualquier explicación sería apreciada.

Editar:

obtuvo los resultados esperados utilizando CDEC. He leído esto en la respuesta de Jonathan Allen en Why does CLng produce different results?

Aquí está el resultado de la prueba:

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

[aritmética de punto flotante puede dar resultados inexactos en Excel] (http://support.microsoft .com/kb/78113) – SeanC

Respuesta

11

La razón es la precision limitada que se puede almacenar en una variable de coma flotante.
Para obtener una explicación completa, debe leer el documento Lo que todo científico informático debe saber sobre la aritmética de punto flotante, por David Goldberg, publicado en la edición de marzo de 1991 de Computing Surveys.

Link to paper

En VBA el valor predeterminado flotante tipo de punto es Double que es el número de coma flotante de un IEEE de 64 bits (8 bytes).

Hay otro tipo: Decimal que es una de 96 bits (12 bytes) firmaron enteros escalados por una potencia variable de 10
En pocas palabras, esto proporciona números de punto flotante a 28 precission dígitos.

para utilizar en su ejemplo:

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

Gracias por el enlace. – Grekoz

3

No es oscura, pero no es necesariamente evidente.

Creo que lo ha respondido, pero el problema básico es uno de los "valores" que es la cantidad de datos que se pueden almacenar en una variable de un tipo determinado.

Si (y esto es muy crudo) se cuenta el número de dígitos en cada uno de los números en su primer ejemplo, verá que tiene 15, mientras que el rango de valores que puede representar un flotante (el tipo predeterminado) es enorme, la precisión está limitada a 15 dígitos (estoy seguro de que alguien correrá para corregir esto, marcaré la casilla del wiki ...)

Así que cuando agrega los dos números, pierde el menos significativo valores para permanecer dentro de la precisión permitida para un flujo.

Haciendo un CDEC va a convertir a un tipo diferente de la variable (decimal) que es capaz de una mayor precisión