2008-11-07 7 views
19

Por qué al guardar un valor de, por ejemplo 40.54 en SQL Server a una columna de tipo real no se volvió a mí de un valor que es más como 40.53999878999 en lugar de 40,54? He visto esto algunas veces, pero nunca he descubierto por qué sucede. ¿Alguien más ha experimentado este problema y, si es así, lo causa?real frente a la coma flotante vs dinero

+0

Este: http://www.panix.com/~arnow/brooklyn_college/diatribe.html – Moshe

Respuesta

43

Eche un vistazo a What Every Computer Scientist Should Know About Floating Point Arithmetic.

Los números de punto flotantes en las computadoras no representan las fracciones decimales exactamente. En cambio, representan fracciones binarias. La mayoría de los números fraccionarios no tienen una representación exacta como una fracción binaria, por lo que hay un poco de redondeo. Cuando una fracción binaria tan redondeada se traduce a una fracción decimal, obtienes el efecto que describes.

Para almacenar los valores del dinero, bases de datos SQL normalmente proporcionan un tipo decimal que almacena los dígitos decimales exactos. Este formato es un poco menos eficiente para las computadoras, pero es bastante útil cuando desea evitar errores de redondeo decimal.

+2

En realidad, es * significativamente * más lento para las computadoras (alrededor de diez veces, debido principalmente a la falta de soporte de hardware), pero la lentitud no importa para la mayoría de las aplicaciones ya que las operaciones numéricas no están cerca del cuello de botella. – crazy2be

+0

Los números de coma flotante no representan ** algunas ** fracciones decimales exactamente. Los números reales en la vida real tampoco representan * algunas * fracciones exactamente. '1/2', por ejemplo, se puede representar exactamente en ambos sistemas. – axiac

12

Los números de coma flotante usan fracciones binarias, y no se corresponden exactamente con las fracciones decimales.

Por dinero, es mejor que cualquiera de almacenar el número de centavos como entero, o usar un tipo de número decimal. Por ejemplo, Decimal (8,2) almacena 8 dígitos, incluidos 2 decimales (xxxxxx.xx), es decir, precisión de ciento.

+0

me gustaría tener tanto de ustedes se ponen los puntos por responder bien. En lugar de almacenar los centavos, estamos usando el valor del dinero. ¿Crees que esto también es una buena práctica? – Middletone

+0

Almacenar los centavos es una mala noticia. Las instituciones financieras a menudo usan centavos fraccionarios en los cálculos, y algunas veces necesitan almacenarlos también. Una vez estuve en un proyecto donde surgió esto luego de que se implementó la aplicación de almacenamiento de centavos. Muy feo. – MusiGenesis

+1

Solo una nota, ¿no es Decimal (8,2) en realidad xxxxxx.xx en lugar de xxxxxxxx.xx? 8 en la definición se refiere a la cantidad total de dígitos antes y después del punto decimal. –

1

Para añadir una aclaración, unos números de punto flotante almacenados en un ordenador se comporta según lo descrito por otros puestos aquí, porque como se ha descrito, se almacena en formato binario. Esto significa que, a menos que su valor (tanto la mantisa como los componentes de exponente del valor) sean potencias de dos, y no puedan representarse exactamente.

Algunos sistemas, por otro lado, almacenan números fraccionarios en decimales (SQL Server Decimal y Numeric data types, y Oracle Number datatype por ejemplo) y luego su representación interna es, por lo tanto, exacta para cualquier número que sea poder de 10. Pero luego los números que no son potencias de 10 no pueden representarse exactamente.

Cuestiones relacionadas