2 votes

Comment corriger une erreur avec des nombres décimaux en Python ?

J'ai un programme qui génère le tableau dont j'ai besoin. Lorsque la différence entre les nombres était assez grande (environ 5 points), tout était correct. J'ai donc décidé d'utiliser la bibliothèque Decimal. Mais quand j'ai ajouté ce module au programme, tout s'est cassé (les chiffres étaient les mêmes). Voici ma sortie (quelques lignes de départ) avec Decimal

0.00402787895809813677877597726251   0.00402787895809813677877597726251
0.00402787895809813677877597726251   0.00402787895809813677877597726251
0.00402787895809813677877597726251   0.00402787895809813677877597726251

Comme vous pouvez le constater, ils sont identiques, mais les numéros de base sont différents. Comment corriger ce bug ?

from decimal import *
getcontext().prec = 30
ls = [1,4,2,1,1,1,2,1,1,1,1,1,1,1,1,2]
#N = Decimal(22)
l = Decimal(0.0040278789580981364238)
r = Decimal(0.0040278789580981370940)
one = Decimal(r-l)/Decimal(22)
print(len(ls))
for elem in ls:
    print(Decimal(l),'\t',Decimal(l)+Decimal(one)*Decimal(elem))
    l+=Decimal(one)*Decimal(elem)

4voto

Tim Pietzcker Points 146308

Vous devez construire les décimales à partir de chaînes de caractères, et non de flottants :

>>> from decimal import Decimal
>>> Decimal(0.0040278789580981370940)
Decimal('0.004027878958098136778775977262512242305092513561248779296875')
>>> Decimal(0.0040278789580981364238)
Decimal('0.004027878958098136778775977262512242305092513561248779296875')
>>> Decimal("0.0040278789580981370940")
Decimal('0.0040278789580981370940')
>>> Decimal("0.0040278789580981364238")
Decimal('0.0040278789580981364238')

Les flottants ont une précision limitée, ce qui signifie que les deux 0.0040278789580981370940 y 0.0040278789580981364238 sont "arrondis" au même nombre en interne (pour plus de détails sur la raison pour laquelle cela est inévitable, voir Arithmétique en virgule flottante : problèmes et limites ).

>>> 0.0040278789580981364238
0.004027878958098137
>>> 0.0040278789580981370940
0.004027878958098137

Si vous utilisez une chaîne de caractères comme contructeur, un Decimal peut être construit avec une précision arbitraire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X