当我用 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
简洁明了,用逻辑右移代替了除以 2 的幂。
当我编译这段代码时:
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
在进行算术右移之前执行一些操作。
这些额外的操作需要什么?为什么算术移位还不够?
最佳答案
原因是无符号除以 2^n 可以非常简单地实现,而有符号除则稍微复杂一些。
unsigned int u;
int v;
u / 4096
相当于 u >> 12
对于 u
的所有可能值.
v / 4096
不等于v >> 12
- 它在 v < 0
时崩溃,因为当涉及负数时,移位和除法的舍入方向不同。
关于c++ - 为什么会发出如此复杂的代码来将有符号整数除以 2 的幂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12692111/