Adresse : http://docs.python.org/3.3/library/decimal.html
Utilité : calculs sur les nombres décimaux.
Syntaxe : import decimal, ou from decimal import *
Le module decimal permet d’effectuer des calculs exacts sur les nombres décimaux, dans les limites d’une précision fixée par l’utilisateur (mais par défaut égale à 28 chiffres significatifs).
Dans la suite, on suppose que le module decimal a été importé par la commande from decimal import *
L’instruction getcontext().prec = n fixe la précision à n chiffres significatifs.
Les “nombres décimaux” (au sens du module decimal) sont obtenus par application du constructeur Decimal (noter le D majuscule) appliqué à un entier ou à une chaîne de caractères (elle-même une représentation d’un flottant, ce qui permet à l’utilisateur de former des valeurs décimales avec une précision donnée). Le module decimal “surcharge” les opérations arithmétiques usuelles, ce qui permet d’effectuer des calculs exacts sur les décimaux (tant qu’on ne dépasse pas la limite de précision qu’on s’est fixée). Commençons par un exemple simple, pour comprendre à quoi le module decimal peut être utile, et en quoi il s’attaque à des problèmes posés par la représentation binaire habituelle des flottants.
|
1 2 3 4 5 6 7 8 |
>>> 0.7 * 0.7 # pour le carré de 0.7, on s'attendrait à trouver 0.49 0.48999999999999994 # mais il y a une imprécision due à la représentation binaire >>> 0.7 * 0.7 == 0.49 # plus problématique, Python ne reconnait pas cette égalité évidente False >>> [0.5 ** n for n in range(1,8)] # on calcule (0.5)n, avec n ∈ {1, · · · , 7} (pas d'erreurs) [0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125] >>> [0.1 ** n for n in [2,3,4]] # on calcule (0.1)n, avec n ∈ {2, 3, 4} [0.010000000000000002, 0.0010000000000000002, 0.00010000000000000002] |
Les “erreurs” ci-dessus ne sont que des conséquences de la représentation en base 2 des flottants : même un nombre aussi inoffensif que 0.1 = 1/(2 ∗ 5) n’est pas représenté de façon exacte en mémoire (contrairement à 0.5 = {2^{-1}}).
Voici ce qu’on obtient, avec les mêmes “calculs”, en important le module decimal :
|
1 2 3 4 5 |
>>> from decimal import * >>> [Decimal("0.1") ** n for n in range(2,6)] [Decimal('0.01'), Decimal('0.001'), Decimal('0.0001'), Decimal('0.00001')] >>> [Decimal("0.5") ** n for n in range(2,6)] [Decimal('0.25'), Decimal('0.125'), Decimal('0.0625'), Decimal('0.03125')] |
Tout cela n’est peut-être pas très impressionnant, alors on va augmenter la précision :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
>>> getcontext().prec = 50 # augmente la précision à 50 chiffres >>> Decimal(1)/Decimal(17) # 1/17 avec 50 chiffres significatifs Decimal('0.058823529411764705882352941176470588235294117647059') √ >>> Decimal(2).sqrt() # 2 avec 50 chiffres significatifs Decimal('1.4142135623730950488016887242096980785696718753769') >>> Decimal(1).exp() # le nombre e avec 50 chiffres significatifs Decimal('2.7182818284590452353602874713526624977572470937000') >>> Decimal(2).ln() # ln 2 avec 50 chiffres significatifs Decimal('0.69314718055994530941723212145817656807550013436026') >>> Decimal(2).ln().as_tuple()[1] # on peut même extraire les chiffres! (6, 9, 3, 1, 4, 7, 1, 8, 0, 5, 5, 9, 9, 4, 5, 3, 0, 9, 4, 1, 7, 2, 3, 2, 1, 2, 1, 4, 5, 8, 1, 7, 6, 5, 6, 8, 0, 7, 5, 5, 0, 0, 1, 3, 4, 3, 6, 0, 2, 6) |
Toujours avec une précision de 50 chiffres, voici la valeur décimale de la somme {\sum\limits_{n=1}^{999}\frac{1}{n}} :
|
1 2 |
>>> sum([Decimal(1)/Decimal(n) for n in range(1,1000)]) n=1 n Decimal('7.4844708605503449126565182043339001765216791697082') |
Un certain nombre des fonctionnalités du module decimal sont des ajouts récents. Le nombre de fonctions mathématiques qui sont compatibles avec ce module est essentiellement limité au logarithme, à l’exponentielle et à la racine carrée.
Pour plus d’informations, on lira les “recettes” (http://docs.python.org/3.3/library/decimal.html#recipes) qui montrent comment programmer le calcul de π, ex, cos(x), sin(x) avec une précision donnée.
Retour à l’accueil du cours Python/Numpy
Sommaire du chapitre 7
- Le module random
- Le module decimal
- Le module fractions
- Le module string
- Le module itertools
- Les modules operator et functools
- Le module time
- La classe Counter du module collections
- La classe deque du module collections
- Le module heapq
- Le module bisect
- Le module copy
- Autres modules et adresses utiles