informatique (MP2I/MPI) · Chapitre 15 · Application directe du cours
Pourquoi le milieu ne s'écrit pas
Diviser pour régner · niveau 2
Énoncé
Le code du cours calcule le milieu par g + (d - g) / 2, et non par (g + d) / 2. Les deux expressions sont mathématiquement égales. Sur quelle machine et pour quelles valeurs diffèrent-elles ?
Corrigé
Elles diffèrent dès que dépasse la capacité du type entier — donc jamais en mathématiques, et bel et bien en machine. Mesuré en C avec des int de bits, pour et :
| Expression | Valeur obtenue |
|---|---|
(g + d) / 2 | |
g + (d - g) / 2 |
Avec INT_MAX , la somme déborde et le résultat est négatif : l'indice obtenu n'appartient même pas à . La recherche accède alors hors du tableau — un défaut du chapitre chap:langage-c, ici au cœur d'un algorithme réputé simple.
Pourquoi la seconde forme est sûre. On a , donc tient dans le type ; et tient aussi. Aucune expression intermédiaire ne sort de , et c'est la propriété qu'on cherche.
Deux remarques pour finir. En OCaml, les entiers font bits et le débordement ne se produirait qu'au-delà de : le défaut est invisible sur la version OCaml du cours, et bien réel sur sa transcription en C. Et sur des entiers non signés, où le débordement est défini modulo , les deux expressions redonnent la même valeur — ce qui a été vérifié. Un défaut qui dépend du type, du langage, et de la taille des données : c'est le pire genre.
Exercices semblables
- Le nombre exact de comparaisons corrigé
- Le comptage des inversions du cours donne 1 sur une liste triée corrigé
- Ce que la rencontre au milieu énumère vraiment corrigé
- Problème — Le tri par partition-fusion sur tableaux : coût exact et stabilité corrigé
- Problème — Élever à une puissance, et Fibonacci en corrigé