int factorielle(int n){
int produit = 1;
for(int i = 1;i <= n;i++){
produit *= i;
}
return produit;
}
//-------------setup----------------
void setup(){
println("le factorielle de 16 est "+factorielle(16));
println("le factorielle de 17 est "+factorielle(17));
}
Voila ce qu'affiche la console :
le factorielle de 16 est 2004189184
le factorielle de 17 est -288522240
Ce qui est absurde. Essayons de comprendre ce qui s'est passé
Codage des entiers
Pour simplifier dans un premier temps, supposons que les nombres ne peuvent être écrits que sur un octet
Le bit de poids faible est le bit des unités, celui de poids fort est celui de la plus grande puissance de 2
Tous les octets dont le bit de poids fort est 0 représentent les entiers positifs et celui dont le bit de poids fort est 1 les négatifs
Tous les octets de 0000 0000 codage de 0 jusqu'à 0111 1111 codage de 127 représentent les positifs
1000 0000 qui vaut 128 en décimal codera un nombre négatif mais lequel ?Que codera 1111 1111?
1111 1111 représente -1 car 1111 1111 + 1 = 1 0000 0000 (dépassement de capacité).Donc 1111 1111 = -1 + 1 0000 0000.
Pour passer de 1000 0000 à 1111 1111 il faut ajouter 127 donc 1000 0000 code -128. Et -128 + 256 = 128 et 128 = 1000 0000
1000 0001 code -127 etc...
Codage d'un entier relatif sur n bits (n=32 ou 64)
il y a $2^n$ codages possibles
De 0 à $2^{n-1} -1$ les entiers positifs codés par en binaire de manière équivalente
De $2^{n-1}$ à $2^n-1$ les entiers négatifs. Si $x$ est un entier négatif entre $-2^{n-1}$ et -1 son codage est le nombre binaire associé à $x+2^n$
Exercice
Vérifier que 479 001 600 = 12! est inférieur à $2^{31}-1$ = 2 147 483 647
mais que 13! = 6 227 020 800 est supérieur ou égal à $2^{31}$ et même à $2^{32}= 4 294 967 296$
Comment expliquer que pour 13! l'ordinateur affiche 1 932 053 504 (utiliser un tableur)