Programmation Python/Numériques

Il existe deux types pour définir des nombres entiers : le type int et le type long. Il existe également un type pour représenter des nombres à virgule : le type float.

Les nombres entiers de type int

modifier

Les int représentent le type le plus facilement représentable sur une architecture donnée. Par exemple, sur une machine 32-bits, la taille d'un int sera de 32-bit, donc un int permettra de représenter des nombres entre   et  , soit entre -2 147 483 648 et 2 147 483 647.

Un littéral int s'écrit tout simplement avec les chiffres de 0 à 9, précédé éventuellement du symbole -. Il est possible d'écrire ce littéral suivant trois bases :

  • la base décimale : le littéral devra commencer par un chiffre entre 1 et 9
  • la base octale (base 8) : le littéral devra commencer par 0 suivi de chiffres de 0 à 7
  • la base hexadécimale (base 16): le littéral devra commencer par 0x suivi de chiffres de 0 à 9 et de lettres de A à F (en minuscule ou majuscule)
x=1
x=0
x=-33
x=4566
x=2147483647
x=076 #équivalent à x=62
x=0xFF #équivalent à x=255
x=0xa1 #équivalent à x=161
Exemple 2 : Quelques entiers int'


Les nombres entiers de type long

modifier

Un entier long est un entier dont la taille n'est limitée que par la mémoire allouée par l'ordinateur à l'interpréteur Python. C'est à dire qu'un long permet d'écrire des entiers aussi grands que l'on veut.

Il existe deux manières d'utiliser des long :

  • il faut rajouter L ou l à la fin d'un littéral entier pour qu'il soit automatiquement long
  • lorsque le résultat d'une opération dépasse la capacité de stockage d'un int, alors, ce résultat est automatiquement convertit en long
x=1L
x=-45l
x=121212121212121212121212121 #Automatiquement converti en long
x=2147483647+1
Exemple 3 : Quelques entiers long'


Il n'est pas nécessaire d'utiliser le type long de manière systématique : pour les entiers de taille raisonnable, le type int est beaucoup plus optimisé.

Pour convertir un long en int (et inversement), il est possible d'utiliser les fonctions int() et long().

x = int(1L) #x est un int
x = long(1) #x est un long
x = int(12121212121212121) #x est quand même un long
Exemple 4 : Utilisation des fonctions int() et long()


Limite entre « integer » et « long »

modifier
Début d’un principe
Fin du principe


Supposons que nous voulions modifier légèrement notre précédent exercice sur la suite de Fibonacci, de manière à obtenir l'affichage d'un plus grand nombre de termes. À priori, il suffit de modifier la condition de bouclage, dans la deuxième ligne. Avec while c<49:, nous devrions obtenir quarante-huit termes. Modifions donc légèrement l'exercice, de manière à afficher aussi le type de la variable principale :

>>> a, b, c = 1, 1, 1
>>> while c<49:
        print (c, " : ", b, type(b))
        a, b, c = b, a+b, c+1
...
...
...  (affichage des 43 premiers termes)
... 
44  :  1134903170 <type 'int'>
45  :  1836311903 <type 'int'>
46  :  2971215073 <type 'long'>
47  :  4807526976 <type 'long'>
48  :  7778742049 <type 'long'>

Que pouvons-nous constater ?

Si nous n'avions pas utilisé la fonction type(), qui nous permet de vérifier à chaque itération le type de la variable b, nous n'aurions rien remarqué du tout : la suite des nombres de Fibonacci s'affiche sans problème (et nous pourrions encore l'allonger de nombreux termes supplémentaires).

Il semble donc que Python soit capable de traiter des nombres entiers de taille illimitée.

L'exercice que nous venons de réaliser indique cependant qu'il se passe « quelque chose » lorsque ces nombres deviennent très grands. Au début du programme, les variables a, b et c sont définies implicitement comme étant du type integer. C'est ce qui se passe toujours avec Python lorsqu'on affecte une valeur entière à une variable, à condition que cette valeur ne soit pas trop grande. Dans la mémoire de l'ordinateur, ce type de donnée est en effet encodé sous la forme d'un bloc de 4 octets (ou 32 bits). Or la gamme de valeurs décimales qu'il est possible d'encoder sur 4 octets seulement s'étend de -2147483648 à + 2147483647 (Voir cours d'informatique générale).

Les calculs effectués avec ce type de variable sont toujours très rapides, parce que le processeur de l'ordinateur est capable de traiter directement par lui-même de tels nombres entiers à 32 bits. En revanche, lorsqu'il est question de traiter des nombres entiers plus grands, ou encore des nombres réels (nombres « à virgule flottante »), les logiciels que sont les interpréteurs et compilateurs doivent effectuer un gros travail de codage/décodage, afin de ne présenter en définitive au processeur que des opérations binaires sur des nombres entiers de 32 bits au maximum.

Vous savez déjà que le type des variables Python est défini de manière dynamique.

Puisqu'il s'agit du type le plus performant (aussi bien en termes de vitesse de calcul qu'en termes d'occupation de place dans la mémoire), Python utilise le type integer par défaut, chaque fois que cela est possible, c'est-à-dire tant que les valeurs traitées sont des entiers compris entre les limites déjà mentionnées plus haut (environ 2 milliards, en positif ou en négatif).

Lorsque les valeurs traitées sont des nombres entiers se situant au-delà de ces limites, leur encodage dans la mémoire de l'ordinateur devient plus complexe. Les variables auxquelles on affecte de tels nombres sont alors automatiquement définies comme appartenant au type « entier long » (lequel est désigné par long dans la terminologie Python).

Ce type long permet l'encodage de valeurs entières avec une précision quasi infinie : une valeur définie sous cette forme peut en effet posséder un nombre de chiffres significatifs quelconque, ce nombre n'étant limité que par la taille de la mémoire disponible sur l'ordinateur utilisé !

Exemple :

>>> a, b, c = 3, 2, 1
>>> while c < 15:
        print (c, ": ", b)
        a, b, c = b, a*b, c+1
	
1 :  2
2 :  6
3 :  12
4 :  72
5 :  864
6 :  62208
7 :  53747712
8 :  3343537668096
9 :  179707499645975396352
10 :  600858794305667322270155425185792
11 :  107978831564966913814384922944738457859243070439030784
12 :  64880030544660752790736837369104977695001034284228042891827649456186234
582611607420928
13 :  70056698901118320029237641399576216921624545057972697917383692313271754
88362123506443467340026896520469610300883250624900843742470237847552
14 :  45452807645626579985636294048249351205168239870722946151401655655658398
64222761633581512382578246019698020614153674711609417355051422794795300591700
96950422693079038247634055829175296831946224503933501754776033004012758368256
>>> 

Dans l'exemple ci-dessus, la valeur des nombres affichés augmente très rapidement, car chacun d'eux est égal au produit des deux termes précédents.

Au départ, les variables a, b et c sont du type integer, puisqu'on leur affecte des petites valeurs numériques entières : 3, 2 et 1. À partir de la 8e itération, cependant, les variables b et a sont automatiquement converties l'une après l'autre dans le type long : le résultat de la multiplication des termes 6 et 7 est en effet déjà bien supérieur à la limite des 2 milliards évoquée plus haut.

La progression continue avec des nombres de plus en plus gigantesques, mais la vitesse de calcul diminue. Les nombres mémorisés sous le type long occupent une place variable dans la mémoire de l'ordinateur, en fonction de leur taille.

Les nombres à virgule flottante (float)

modifier

Un nombre à virgule flottante est un nombre décimal qu'il est possible de représenter par sa mantisse et son exposant. Par exemple, le nombre 125,789 est représentable par le couple (mantisse = 1,25789, exposant = 2). La mantisse étant toujours comprise entre -10 et 10 exclus.

Les nombres sont traduits par la formule  .

Les limites dépendent de l'architecture de la machine et sont équivalentes au type de donnée double du langage C.

Les littéraux peuvent s'écrire avec les chiffres, le caractère point pour indiquer la séparation entre la partie entière et la partie décimale et la lettre 'e' ou 'E' pour spécifier l'exposant.

x = 1.234
x = 1.0 #Notons qu'un entier peut être un flottant
x = 1. #Même résultat que précédemment
x = 1.234e54 #C'est à dire <math>1.234*10^{54}</math>
x = 1.234E54 #idem
x = -1.454e-2 #La mantisse et l'exposant peuvent être négatifs
Exemple 5 : nombres à virgules


Essayons donc ce type de données dans un nouveau petit programme :

>>> a, b, c = 1., 2., 1	            # => a et b seront du type 'float'
>>> while c <18:
...     a, b, c = b, b*a, c+1
...     print (b)

2.0
4.0
8.0
32.0
256.0
8192.0
2097152.0
17179869184.0
3.6028797019e+16
6.18970019643e+26
2.23007451985e+43
1.38034926936e+70
3.07828173409e+113
4.24910394253e+183
1.30799390526e+297
         Inf
         Inf

Comme vous l'aurez certainement bien compris, nous affichons cette fois encore une série dont les termes augmentent extrêmement vite, chacun d'eux étant égal au produit des deux précédents. Au huitième terme, nous dépassons déjà largement la capacité d'un integer. Au neuvième terme, Python passe automatiquement à la notation scientifique (« e+n » signifie en fait : « fois dix à l'exposant n »). Après le quinzième terme, nous assistons à nouveau à un dépassement de capacité (sans message d'erreur) : les nombres vraiment trop grands sont tout simplement notés « inf » (pour « infini »).

Le type float utilisé dans notre exemple permet de manipuler des nombres (positifs ou négatifs) compris entre 10e-308 et 10e+308 avec une précision de 12 chiffres significatifs. Ces nombres sont encodés d'une manière particulière sur 8 octets (64 bits) dans la mémoire de la machine : une partie du code correspond aux 12 chiffres significatifs, et une autre à l'ordre de grandeur (exposant de 10).

Exercices

  1. Écrivez un programme qui convertisse en radians un angle fourni au départ en degrés, minutes, secondes.
  2. Écrivez un programme qui convertisse en degrés, minutes, secondes un angle fourni au départ en radians.
  3. Écrivez un programme qui convertisse en degrés Celsius une température exprimée au départ en degrés Fahrenheit, ou l'inverse.
    La formule de conversion est :  
  4. Écrivez un programme qui calcule les intérêts accumulés chaque année pendant 20 ans, par capitalisation d'une somme de 100 euros placée en banque au taux fixe de 4,3 %
  5. Une légende de l'Inde ancienne raconte que le jeu d'échecs a été inventé par un vieux sage, que son roi voulut remercier en lui affirmant qu'il lui accorderait n'importe quel cadeau en récompense. Le vieux sage demanda qu'on lui fournisse simplement un peu de riz pour ses vieux jours, et plus précisément un nombre de grains de riz suffisant pour que l'on puisse en déposer 1 seul sur la première case du jeu qu'il venait d'inventer, deux sur la suivante, quatre sur la troisième, et ainsi de suite jusqu'à la 64e case.
    Écrivez un programme Python qui affiche le nombre de grains à déposer sur chacune des 64 cases du jeu. Calculez ce nombre de deux manières :
    • le nombre exact de grains (nombre entier)
    • le nombre de grains en notation scientifique (nombre réel)

Solution

  1. # Conversion degrés -> radians
    # Rappel : un angle de 1 radian est un angle qui correspond à une portion
    # de circonférence de longueur égale à celle du rayon.
    # Puisque la circonférence vaut 2 pi R, un angle de 1 radian correspond
    # à 360° / 2 pi , ou encore à 180° / pi
    
    # Angle fourni au départ en degrés, minutes, secondes :
    deg, min, sec  = 32, 13, 49
    
    # Conversion des secondes en une fraction de minute :
    # (le point décimal force la conversion du résultat en un nombre réel)
    fm = sec/60.
    # Conversion des minutes en une fraction de degré :
    fd = (min + fm)/60
    # Valeur de l'angle en degrés "décimalisés" :
    ang = deg + fd
    # Valeur de pi :
    pi = 3.14159265359
    # Valeur d'un radian en degrés :
    rad = 180 / pi
    # Conversion de l'angle en radians :
    arad = ang / rad
    # Affichage :
    print (deg, "°", min, "'", sec, '" =', arad, "radian(s)")
    
  2. Réfléchissez !
  3. # Conversion °Fahrenheit <-> °Celsius
    
    # A) Température fournie en °C :
    tempC = 25
    # Conversion en °Fahrenheit :
    tempF = tempC * 1.8 + 32
    # Affichage :
    print tempC, "°C =", tempF, "°F"
    
    # B) Température fournie en °F :
    tempF = 25
    # Conversion en °Celsius :
    tempC = (tempF - 32) / 1.8
    # Affichage :
    print (tempF, "°F =", tempC, "°C")
    
  4. Réfléchissez !
  5. >>> a, b = 1, 1				# variante :  a, b = 1., 1
    >>> while b<65:
    ...     print (b, a)
    ...     a,b = a*2, b+1
    ...
    

Les nombres complexes

modifier

Python est un des rares langages à proposer un type de base pour les nombres complexes  . Un nombre complexe est un nombre composé d'une partie réelle et d'une partie imaginaire. On note   une des racines du polynôme  .

Dans certains contextes, (comme la physique), la racine de -1 est notée j. C'est ce qui se fait en Python.

Un littéral complexe s'écrit donc : a + bj, avec a et b des variables de type float. Attention, j doit être précédé d'un nombre car sinon, Python l'interprétera comme étant la variable j. Il ne doit pas y avoir d'espace entre ce nombre et j.

x = 1 + 1j
x = 1.2e3 + 1.5e7j
x = 5j + 4 
x = 1 + x*1j
Exemple 5 : quelques nombres complexes