Большинство компиляторов пойдут даже дальше, чем уменьшение деления на степени 2 на сдвиги - они часто преобразуют целочисленное деление на константу в последовательность инструкций умножения, сдвига и сложения, чтобы получить результат вместо использования встроенного процессора -в инструкции деления (если есть даже одна).
Например, MSVC преобразует деление на 71 в следующее:
// 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
Таким образом, вы получаете деление на 71 с умножением, парой смен и добавлением пары.
Подробнее о происходящем можно узнать из книги Генри Уоррена "Восхищение хакера" или на веб-странице компаньона:
Есть онлайновая добавленная глава , которая предоставляет некоторую дополнительную информацию о делении на константы с использованием умножения / сдвига / сложения с магическими числами, и страницу с небольшой программой на JavaScript , которая Я вычислю магические числа, которые вам нужны.
Стоит прочитать сопутствующий сайт для книги (как и для книги), особенно если вы заинтересованы в микрооптимизации на битовом уровне.
Другая статья, которую я обнаружил только что, в которой обсуждается эта оптимизация: http://blogs.msdn.com/devdev/archive/2005/12/12/502980.aspx