int
Comme nous l'avons vu dans la section précédente, il existe une limite aux valeurs que l'on peut stocker dans une variable. Dans le cas des entiers, cette limite n'est cependant pas toujours la même et dépend de la machine sur laquelle votre programme va s'exécuter.
Les entiers sont stockés sur la machine sous la forme de nombres en base binaire. Il y a cependant une limite sur le nombre de chiffres que l'on peut stocker dans une variable de type int
. Cette limite est de 32 chiffres sur les machines récentes, mais peut être de 16 sur d'autres. On considérera pour l'instant que la limite est de 32, puisque c'est très probablement le cas sur la machine que vous utilisez. La mémoire utilisée pour stocker une variable de type int
est donc de 32 chiffres binaires, que l'on appelle bits. On dit ainsi que l'on manipule des entiers 32 bits. Cela correspond également à quatre octets, un octet correspondant à huit bits.
Il existe une différence entre la notation binaire que nous avons vue dans la section précédente et le stockage des nombres dans une variable de 32 bits. Cette différence porte sur la manière de stocker les nombres négatifs. En base binaire "classique", on écrit un nombre négatif en base 2 de la même manière qu'en base 10 : en mettant un signe - devant. Le nombre -9 s'écrit ainsi -1001. Or, dans une variable entière sur 32 bits, on dispose de 32 chiffres pour stocker un nombre et de rien d'autre. On doit donc utiliser ces chiffres eux-mêmes pour déterminer si le nombre est négatif ou non.
Pour comprendre comment les nombres négatifs sont stockés, prenons l'exemple d'un compteur kilométrique d'une voiture (suffisamment ancienne pour que ce compteur soit mécanique), composé de 8 chiffres. Lorsque l'on avance de 100m, le chiffre de droite tourne d'un cran, et passe au chiffre suivant. S'il passe de 9 à 0, le chiffre suivant tourne d'un cran également, etc.

Supposons maintenant qu'il soit possible de le faire remonter en arrière. Que se passe-t-il lorsque tous les chiffres sont à 0 et que l'on le fait tourner à l'envers ? Votre compteur aura probablement tous ses chiffres qui repasseront à 9. La valeur "-1" sera alors représentée par l'affichage : 99999999 (tous les chiffres à 9).

Comment déterminer si ce nombre 99999999 représente la valeur -1, ou la très grande valeur positive que nous lisons ? Il n'y a pas de recette miracle : il faut décider une fois pour toutes que les nombres supérieurs à une certaine valeur seront des nombres négatifs. On peut par exemple dire que tous les nombres au dessus de 50000000 doivent être considérés comme négatifs. Le plus grand nombre positif pouvant être représenté est alors 49999999. La valeur 50000000 représente le nombre -50000000, puisque 50000000 + 50000000 = 100000000, soit 00000000 sur notre compteur à 8 chiffres.
Ceci est exactement le principe que l'on applique pour stocker des entiers négatifs dans une variable de 32 bits. La valeur -1 est représentée par le nombre 11111111111111111111111111111111 (32 bits à 1), la valeur -2 par 11111111111111111111111111111110, etc. On définit que les nombres doivent être considérés comme négatifs à partir de la valeur : 10000000000000000000000000000000. Le plus grand entier que l'on peut stocker est alors : 01111111111111111111111111111111 (un zéro, suivi de 31 uns).
Si l'on traduit ces nombres en base 10, on en déduit que la plus grande valeur que l'on peut stocker sur un entier 32 bits est de 231-1, c'est à dire 2147483647 (un peu plus de deux milliards). La valeur la plus petite que l'on puisse stocker est -231, soit -2147483648.
Exercice : on a évoqué le fait que sur certaines machines, une variable de type int
est stockée sur 16 bits seulement. Quelles sont à votre avis les valeurs minimales et maximales d'une variable int
sur ces machines ?
Solution : En appliquant le même principe, on définit que les nombres négatifs sont les nombres à partir de 1000000000000000 (un 1 suivi de 15 zéros). Le plus grand nombre (positif) est donc 215 - 1 soit 32767, et le plus petit nombre est -215, soit -32768.
Exercice : déterminer un critère simple pour déterminer à partir de sa notation binaire 32 bits, si un nombre est positif ou négatif.
Solution : Les nombres négatifs étant ceux à partir de 10000000000000000000000000000000, il suffit de regarder le premier bit de la valeur. S'il est à 1, c'est un nombre négatif, s'il est à 0, c'est un nombre positif.
Nous venons de voir qu'il y a une limite aux valeurs que peut prendre un entier. Que se passe-t-il lorsque l'on dépasse cette limite ? Pour le voir, testez le programme suivant et essayez de comprendre le résultat.
#include <stdio.h> int main() { int grandeValeur = 2147483647; printf("Valeur de départ : %d\n", grandeValeur); grandeValeur++; printf("Après incrémentation : %d\n", grandeValeur); grandeValeur--; printf("Après décrémentation : %d\n", grandeValeur); return 0; }
Le programme devrait afficher le texte suivant :
Valeur de départ : 2147483647 Après incrémentation : -2147483648 Après décrémentation : 2147483647
La valeur initiale 2147483647 correspond à la plus grande valeur positive que peut contenir une variable int
. Elle correspond à la valeur binaire 01111111111111111111111111111111. Si on l'incrémente de 1, on obtient en binaire, 10000000000000000000000000000000, qui est la toute première valeur négative que l'on peut représenter. On a en fait "fait le tour" des valeurs possibles.
On aurait pu "faire le tour" de nombreuses manières différentes. Une multiplication du nombre initial par 5 aurait ainsi donné la valeur 2147483643
, après deux dépassements de capacité en une même opération.
La machine ne fait aucune vérification de dépassement de la capacité d'un entier. Lorsque vous écrivez un programme, vous devez donc systématiquement vérifier vous-mêmes que les valeurs que vous manipulez ne risquent pas de dépasser les valeurs maximales qu'un int
permet de gérer. Si vous ne le faites pas, vous risquez de rencontrer des erreurs d'exécution difficiles à détecter.