为什么如此复杂的code发出由两个功率分配有符号整数? [英] Why is such complex code emitted for dividing a signed integer by a power of two?
问题描述
当我编译这个code。与VC ++ 10:
When I compile this code with VC++10:
DWORD ran = rand();
return ran / 4096;
我得到这个拆卸:
I get this disassembly:
299: {
300: DWORD ran = rand();
00403940 call dword ptr [__imp__rand (4050C0h)]
301: return ran / 4096;
00403946 shr eax,0Ch
302: }
00403949 ret
它是干净简洁和由二的幂与一个逻辑右移取代表决。
which is clean and concise and replaced a division by a power of two with a logical right shift.
然而,当我编译这个code:
Yet when I compile this code:
int ran = rand();
return ran / 4096;
我得到这个拆卸:
I get this disassembly:
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
这是做算术右移之前执行某些操作。
that performs some manipulations before doing a right arithmetic shift.
什么是需要这些额外的操作?为什么算术移位不够?
What's the need for those extra manipulations? Why is an arithmetic shift not enough?
推荐答案
其原因是无符号除以2 ^ n可以非常简单地实现,而符号的除法稍微复杂一些。
The reason is that unsigned division by 2^n can be implemented very simply, whereas signed division is somewhat more complex.
unsigned int u;
int v;
U / 4096
等同于 U>> 12
为 U
所有可能的值。
u / 4096
is equivalent to u >> 12
for all possible values of u
.
V / 4096
是不会等同于 V>> 12
- 它发生故障时 V< 0
,由于舍入方向是相对于移动时负数参与分工不同。
v / 4096
is NOT equivalent to v >> 12
- it breaks down when v < 0
, as the rounding direction is different for shifting versus division when negative numbers are involved.
这篇关于为什么如此复杂的code发出由两个功率分配有符号整数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!