Définition
Les entiers suffisent tant qu'on compte des choses. Ils cessent de suffire dès qu'on mesure ou qu'on partage : 1.75 mètre, 19.99 euros ou une moyenne de 12.5 ne tombent sur aucun nombre rond. Le type float existe pour ces valeurs à partie décimale.
Le séparateur décimal est le point, jamais la virgule, qui sert en Python à séparer des éléments. Écrire un montant avec une virgule ne déclenche donc aucune erreur : cela fabrique deux nombres au lieu d'un, bien plus difficile à repérer. Une variable devient un float dès qu'un point décimal apparaît dans sa valeur, sans rien à déclarer.
prix = 19.99
taux = 0.2
total = prix * (1 + taux)
print(type(total))
# <class 'float'> le résultat a hérité de la virguleLe nom vient de « floating point », virgule flottante : la position de la virgule n'est pas figée. Le nombre est retenu comme une suite de chiffres et un décalage, et ce décalage bouge pour loger 0.000012 comme 12000000.0 dans la même place. C'est ce qui le sépare de l'int, qui ne connaît que les entiers.
Rien ne dit à la lecture lequel des deux on manipule : interroger le type d'une valeur tranche la question dès qu'un calcul rend un résultat inattendu.
Une division suffit à en fabriquer un
Un .0 finit toujours par surgir à l'affichage, sur un compteur où personne n'a jamais écrit de virgule. Une règle l'explique : dès qu'un nombre à virgule entre dans un calcul, le résultat est un nombre à virgule. La division simple en produit un même entre deux entiers, parce qu'elle donne le quotient exact et non le quotient tronqué.
Le tableau ci-dessous rassemble les cas les plus courants ; c'est la colonne de droite qu'il faut suivre.
| Calcul | Résultat | Type obtenu |
|---|---|---|
7 / 2 | 3.5 | float, toujours |
6 / 2 | 3.0 | float, malgré le compte rond |
7 // 2 | 3 | int, c'est la division entière |
3 + 0.5 | 3.5 | float, par contamination |
2 ** 0.5 | 1.4142... | float, la racine carrée |
La deuxième ligne surprend toujours : le calcul tombe juste, et le résultat reste un nombre à virgule. Un compteur qui a croisé une division s'affichera donc « 3.0 » jusqu'à la fin du programme. Le corriger à l'affichage traite le symptôme ; l'opérateur de division entière //, ou une conversion explicite, règlent le problème là où il naît.
Le piège de la précision
Un ordinateur ne stocke rien en base dix. Un nombre à virgule est écrit en binaire sur une place fixe, et beaucoup de décimales banales n'ont pas d'écriture binaire finie, à commencer par 0.1. Python retient la valeur la plus proche qu'il sait représenter, et cet écart ressort dès qu'on additionne.
0.1 + 0.2
# 0.30000000000000004 l'écart ne s'efface pas, il se cumule
0.1 + 0.2 == 0.3
# FalseCe n'est pas un défaut de Python : tous les langages qui suivent la même norme donnent le même résultat. La conséquence pratique est bien réelle : comparer deux nombres à virgule avec == dans une condition finit toujours par surprendre, même sur des valeurs identiques à l'écran. La parade consiste à comparer un écart plutôt qu'une égalité, avec math.isclose(a, b) ou en vérifiant que abs(a - b) reste sous un seuil choisi.
Un float conserve environ quinze à dix-sept chiffres significatifs : largement assez pour des mesures ou des moyennes, insuffisant dès qu'une valeur doit rester exacte au centime près.
Convertir, arrondir, afficher
Tout ce qui entre dans un programme entre sous forme de texte : une saisie au clavier, un champ de formulaire, une colonne de fichier. La fonction float() en tire un nombre, passage obligé après un input, qui renvoie toujours une chaîne. Sans elle, additionner ce texte lève une TypeError ; avec elle, une saisie mal formée lève une ValueError, qui se rattrape.
Le nombre en main, trois besoins se présentent, chacun avec son outil.
saisie = "19.99"
montant = float(saisie)
int(montant) # 19, la partie décimale est coupée
round(montant) # 20, l'arrondi au plus proche
round(montant, 1) # 20.0, arrondi mais toujours un float
print(f"{montant:.2f} euros")
# 19.99 euros la valeur en mémoire n'a pas bougéLa fonction int() tronque, round() arrondit, et le formatage d'une f-string ne touche qu'à l'affichage. Cette dernière distinction compte : arrondir pour l'écran ne doit jamais modifier la valeur gardée pour les calculs suivants, sous peine de voir un total s'écarter de la somme de ses lignes.
round() arrondit les cas d'égalité vers le nombre pair : round(2.5) vaut 2 et non 3. La règle évite un biais sur de longues séries, mais elle surprend quiconque compare un total Python à celui d'un tableur.
Questions fréquentes
Faut-il utiliser float pour des montants en euros ?
Non, pas dès qu'il s'agit de comptabilité. Les écarts s'accumulent au fil des additions et finissent par produire un centime de différence sur une facture, ce qui suffit à la faire refuser. Deux solutions tiennent : le module decimal, qui calcule en base dix, ou des montants stockés en centimes, sous forme d'entiers.
Que représentent inf et nan ?
float("inf") est l'infini, que produit un dépassement de capacité, et float("nan") signifie « pas un nombre », résultat d'une opération indéterminée. Une division par zéro, elle, lève une ZeroDivisionError plutôt que de donner l'infini. Curiosité utile au débogage : nan n'est jamais égal à lui-même.
Comment savoir si une valeur est un nombre à virgule ?
Avec isinstance(valeur, float), qui répond par un bool. Attention au faux négatif : isinstance(3, float) est faux, alors que 3 se comporte comme 3.0 dans tous les calculs. Pour accepter n'importe quel nombre, mieux vaut tester les deux types ensemble avec isinstance(valeur, (int, float)).