¿Cómo lidiar con los errores de redondeo de tipos flotantes para cálculos financieros en Python SQLite?

StackOverflow https://stackoverflow.com/questions/1801307

  •  05-07-2019
  •  | 
  •  

Pregunta

Estoy creando una aplicación financiera y parece que mis flotadores en sqlite están flotando. A veces, un 4.0 será un 4.000009, y un 6.0 será un 6.00006, cosas así. ¿Cómo puedo hacer esto más exacto y no afectar mis cálculos financieros?

Los valores vienen de Python si eso importa. No estoy seguro de qué área provienen los números desordenados.

¿Fue útil?

Solución

Este es un problema común al usar SQLite ya que no tiene un tipo de moneda.
Como dijo S.Mark, puede usar la Decimal biblioteca de representación. Sin embargo, SQLite 3 solo admite números binarios de punto flotante (tipo de sqlite REAL), por lo que tendría que almacenar el flotante codificado decimal como TEXTO o BLOB o convertir a REAL (pero luego volvería a un flotador binario de 64 bits)
Entonces, considere el rango de números que necesita representar y si necesita poder realizar cálculos desde la Base de datos.

Puede que sea mejor utilizar una base de datos diferente que admita tipos NUMÉRICOS, por ejemplo. MYSql , PostgreSQL , Firebird

Otros consejos

Al ver que se trata de una aplicación financiera, si solo tiene cálculos con 2 o 3 decimales, puede almacenar todos los datos internamente como números enteros y convertirlos a flotación para fines de presentación .

Por ejemplo,

6.00 -> 600
4.35 -> 435

La mayoría de la gente probablemente usaría Decimal para esto, sin embargo, si esto no se asigna a un tipo de base de datos, puede tener un impacto en el rendimiento.

Si el rendimiento es importante, es posible que desee considerar el uso de enteros para representar una unidad monetaria adecuada; a menudo, los centavos o décimas de centavos están bien.

Deben existir reglas de negocios sobre cómo deben redondearse los montos en diversas situaciones y debe realizarse pruebas que cubran cada escenario.

Use Decimal para manipular sus cifras, luego use pickle para guardarlo y cargarlo desde SQLite como texto, ya que no maneja tipos numéricos.

Finalmente, use unitest y doctest , para las operaciones financieras, debe asegurarse de que todo el código haga lo que se supone que debe hacer en cualquier circunstancia. No se pueden corregir errores de la forma como, digamos, una red social ...

Tienes que usar números decimales. Los números decimales se pueden representar exactamente.

En coma flotante decimal, 0.1 + 0.1 + 0.1 - 0.3 es exactamente igual a cero. En punto flotante binario, el resultado es 5.5511151231257827e-017.

Por lo tanto, solo prueba el decimal:

import decimal
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top