La plupart des compilateurs vont même au-delà de la réduction de la division par des puissances de 2 en décalages - ils convertissent souvent la division d'un nombre entier par une constante en une série d'instructions de multiplication, de décalage et d'addition pour obtenir le résultat au lieu d'utiliser l'instruction de division intégrée du CPU (si tant est qu'il y en ait une).
Par exemple, MSVC convertit la division par 71 en ce qui suit :
// volatile int y = x / 71;
8b 0c 24 mov ecx, DWORD PTR _x$[esp+8] ; load x into ecx
b8 49 b4 c2 e6 mov eax, -423447479 ; magic happens starting here...
f7 e9 imul ecx ; edx:eax = x * 0xe6c2b449
03 d1 add edx, ecx ; edx = x + edx
c1 fa 06 sar edx, 6 ; edx >>= 6 (with sign fill)
8b c2 mov eax, edx ; eax = edx
c1 e8 1f shr eax, 31 ; eax >>= 31 (no sign fill)
03 c2 add eax, edx ; eax += edx
89 04 24 mov DWORD PTR _y$[esp+8], eax
Vous obtenez donc un diviseur par 71 avec un multiplicateur, quelques décalages et quelques additions.
Pour plus de détails sur ce qui se passe, consultez le livre "Hacker's Delight" d'Henry Warren ou la page web correspondante :
Il y a un chapitre ajouté en ligne qui fournit des informations sur l'addition à propos de la division par des constantes en utilisant la multiplication/shift/add avec des nombres magiques, et un avec un petit programme JavaScript qui calculera les chiffres magiques dont vous avez besoin.
Le site d'accompagnement du livre vaut la peine d'être lu (tout comme le livre), en particulier si vous êtes intéressé par les micro-optimisations au niveau du bit.
Un autre article que je viens de découvrir traite de cette optimisation : http://blogs.msdn.com/devdev/archive/2005/12/12/502980.aspx