Wenn ich kompilieren diesen Code mit VC++ 10:Warum wird solch komplexer Code zum Teilen einer vorzeichenbehafteten Ganzzahl mit einer Potenz von zwei ausgegeben?
DWORD ran = rand();
return ran/4096;
Ich erhalte diese Demontage:
299: {
300: DWORD ran = rand();
00403940 call dword ptr [__imp__rand (4050C0h)]
301: return ran/4096;
00403946 shr eax,0Ch
302: }
00403949 ret
, die eine Division durch eine Zweierpotenz mit einem logischen Recht sauber und präzise und ersetzt ist Verschiebung.
Doch wenn ich kompilieren diesen Code:
int ran = rand();
return ran/4096;
ich diese Demontage erhalten:
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
, die einige Manipulationen durchführt, bevor sie eine richtige Stellenverschiebung tun.
Was sind die zusätzlichen Manipulationen? Warum reicht eine arithmetische Verschiebung nicht aus?
FWIW, in C89 und C++ 03 wurde implementiert, wie Integer Division Runden für negative Operanden. In C99 und C++ 11 ist es nicht. –
So viele upvotes dafür? –
@AlexeyFrune Diese ist eigentlich ziemlich gut im Vergleich zu einigen anderen Dingen, die massiv verbessert werden. Also sehe ich es nicht als unverdient an. – Mysticial