我需要找到以下C代码的最快等价。
int d = 1 << x; /* d=pow(2,x) */
int j = 2*d*(i / d) + (i % d);
我的想法是将左上32位x移位
例如,以下i,x = 5:
1010 1010 1010 1010
将成为:
0101 0101 010 0 1010
是否有汇编命令?如何快速执行此操作?
答案 0 :(得分:9)
int m = (1 << x) - 1;
int j = (i << 1) - (i & m);
<强>更新强>:
或者可能更快:
int j = i + (i & (~0 << x));
答案 1 :(得分:5)
x86 32位汇编(AT&amp; T语法):
/* int MaskedShiftByOne(int val, int lowest_bit_to_shift) */
mov 8(%esp), %ecx
mov $1, %eax
shl %ecx, %eax ; does 1 << lowest_bit_to_shift
mov 4(%esp), %ecx
dec %eax ; (1 << ...) - 1 == 0xf..f (lower bitmask)
mov %eax, %edx
not %edx ; complement - higher mask
and %ecx, %edx ; higher bits
and %ecx, %eax ; lower bits
lea (%eax, %edx, 2), %eax ; low + 2 * high
ret
这应该适用于Linux和Windows。
编辑:i + (i & (~0 << x))
更短:
mov 4(%esp), %ecx
mov $-1, %eax
mov 8(%esp), %edx
shl %edx, %eax
and %ecx, %eax
add %ecx, %eax
ret
士气:不要从装配开始。如果你确实需要它,请反汇编高度优化的编译器输出...
答案 2 :(得分:4)
向左移动一个上x
位。
unsigned i = 0xAAAAu;
int x = 5;
i = (i & ((1 << x) - 1)) | ((i & ~((1 << x) - 1)) << 1); // 0x1554A;
一些解释:
(1 << x) - 1
使掩码为零32 - x
位。
~((1 << x) - 1)
使掩码为零x
位。
在归零后,我们将上部和or
移到一起。
在Codepad上试试。
答案 3 :(得分:3)
int m = (1 << x) - 1;
int j = ((i & ~m) << 1) | (i & m);
没有汇编命令可以执行您想要的操作,但我提供的解决方案更快,因为它避免了划分。
答案 4 :(得分:1)
Intel语法:
mov ecx,[esp+4] ;ecx = x
mov eax,[esp+8] ;eax = i
ror eax,cl
inc cl
clc
rcl eax,cl
ret
道德:高度优化的编译器输出......不是。