Почему такой сложный код испускается для деления целого числа со знаком на степень два?
Когда я компилирую этот код с VC ++ 10:
DWORD ran = rand();
return ran / 4096;
Я получаю эту разборку:
299: {
300: DWORD ran = rand();
00403940 call dword ptr [__imp__rand (4050C0h)]
301: return ran / 4096;
00403946 shr eax,0Ch
302: }
00403949 ret
который является чистым и кратким и заменяет деление на степень два с логическим сдвигом вправо.
Тем не менее, когда я компилирую этот код:
int ran = rand();
return ran / 4096;
Я получаю эту разборку:
299: {
300: int ran = rand();
00403940 call dword ptr [__imp__rand (4050C0h)]
301: return ran / 4096;
00403946 cdq
00403947 and edx,0FFFh
0040394D add eax,edx
0040394F sar eax,0Ch
302: }
00403952 ret
который выполняет некоторые манипуляции перед выполнением правильного арифметического сдвига.
Какая необходимость в этих дополнительных манипуляциях? Почему арифметического сдвига недостаточно?