2009-11-26 4 views
4

Je crée une application financière et il semble que mes flotteurs dans sqlite flottent. Parfois, un 4.0 sera un 4.000009, et un 6.0 sera un 6.00006, des choses comme ça. Comment puis-je les rendre plus exactes et ne pas affecter mes calculs financiers?Comment gérer les erreurs d'arrondi des types flottants pour les calculs financiers dans Python SQLite?

Les valeurs proviennent de Python si cela est important. Je ne sais pas de quelle région proviennent les numéros foirés.

+0

http://docs.python.org/tutorial/floatingpoint.html – bernie

+0

http://docs.sun.com/source/806-3568/ncg_goldberg.html – Ken

+0

Veuillez générer un exemple minimal. –

Répondre

3

Ceci est un problème commun en utilisant SQLite car il ne dispose pas d'un type de devise.
Comme l'a dit S. Mark, vous pouvez utiliser la bibliothèque de représentation Decimal. Cependant SQLite 3 ne supporte que les nombres à virgule flottante binaire (sqlite type REAL) donc vous devez stocker le flottant décimal encodé en texte ou en BLOB ou le convertir en REAL (mais vous reviendrez à un flottant binaire 64bit)
Considérez donc la gamme de nombres que vous devez représenter et si vous devez être capable d'effectuer des calculs à partir de la base de données.

Il est peut-être préférable d'utiliser un DB différent prenant en charge les types NUMERIC, par ex. MYSql, PostgreSQL, Firebird

+0

ouais vous mai ont raison mais sqlite est si facile et flexible – Recursion

4

Voyant que cela est une application financière, si vous suffit calculs jusqu'à 2 ou 3 décimales, vous pouvez stocker toutes les données en interne comme des entiers, et Convertissez-les uniquement en float à des fins de présentation.

E.g.

6.00 -> 600 
4.35 -> 435 
+0

Je pense que c'est un conseil terrible, avec * floats * 600 $ seront arrondis à 600,01 $. * double * vous achète quelques chiffres plus importants mais ce n'est toujours pas la bonne chose à faire - et si ce code se retrouve dans un logiciel financier est utilisé pour des transactions d'un milliard de dollars? –

+0

C'est pourquoi j'ai dit que vous pouvez utiliser l'arithmétique entière (par exemple 4003, qui est en fait 4.003, aura une représentation précise en arithmétique entière), sauf si vous voulez dire quelque chose d'autre? Par exemple. S'il vous plaît, élaborer. –

+0

Pas vraiment une bonne idée puisque le taux de conversion international ont plus de deux chiffres après le point. Comme 1 euros était 6,55956 francs. –

0

Vous devez utiliser des nombres décimaux. Les nombres décimaux peuvent être représentés exactement. En virgule flottante, 0.1 + 0.1 + 0.1 - 0.3 est exactement égal à zéro. En binaire en virgule flottante, le résultat est 5.5511151231257827e-017.

, essayez juste décimales:

import decimal 
1

La plupart des personnes utiliseraient Probablement Decimal pour cela, mais si cela ne correspond pas à un type de base de données, vous pourriez avoir un impact sur les performances.

Si la performance est importante, vous pouvez envisager d'utiliser des entiers pour représenter une unité monétaire appropriée - souvent des centimes ou des centièmes de centimes suffisent.

Il devrait y avoir des règles commerciales sur la façon dont les montants doivent être arrondis dans diverses situations et vous devriez avoir des tests couvrant chaque scénario.

1

Utilisez Decimal pour manipuler vos figures, puis utilisez pickle pour l'enregistrer et le charger à partir de SQLite sous forme de texte, car il ne gère pas les types numériques. Enfin, utilisez unitest et doctest, pour les opérations financières, vous voulez vous assurer que tout le code fait ce qu'il est censé faire dans toutes les circonstances. Vous ne pouvez pas corriger les bugs sur le chemin comme, disons, avec un réseau social ...

Questions connexes