好的,伙计们,我知道我想做什么,但我不知道它是否已经存在(作为一个函数或理论上)或如何表达它,所以我需要你的帮助:
10101110
(lsb) 示例:
因此,我们想象函数CROPLEFT(X,POS)的最终结果,其中X = 10101110,POS = 1,将返回00001110
。
有什么想法吗?
答案 0 :(得分:12)
一块蛋糕。
y = ~x; // We like working with 1's, not 0's.
y &= -y; // Mask off all but the lowest-set bit
x &= y-1; // Make a mask for the bits below that and apply it.
并添加了位置参数:
y = ~x & -1U<<pos; // Change 1U to a larger type if needed.
y &= -y;
x &= y-1;
关键因素是第二行,并且您可以通过应用逻辑和y
来仅使用其最低设置位替换值-y
。可悲的是,除非你有一个特殊的cpu指令,否则没有获得最高设置位的运气,所以你很幸运,你的问题要求最低。
答案 1 :(得分:3)
好的,到底是什么:
return x & ((x ^ (x + (1UL << POS))) | ((1UL << POS) - 1))
对于它的价值,它们都使用gcc-4.7 -O3编译。 R ..在左边,我在右边:(使用无符号长和1UL两个)
.p2align 4,,15 .p2align 4,,15
.globl zapleft .globl zapleft2
.type zapleft, @function .type zapleft2, @function
zapleft: zapleft2:
.LFB0: .LFB1:
.cfi_startproc .cfi_startproc
movl %esi, %ecx movl %esi, %ecx
movq %rdi, %rax movl $1, %edx
movq $-1, %rdx salq %cl, %rdx
salq %cl, %rdx leaq (%rdx,%rdi), %rax
notq %rax subq $1, %rdx
andq %rax, %rdx xorq %rdi, %rax
movq %rdx, %rax orq %rdx, %rax
negq %rax andq %rdi, %rax
andq %rdx, %rax ret
subq $1, %rax .cfi_endproc
andq %rdi, %rax .LFE1:
ret .size zapleft2, .-zapleft2
.cfi_endproc
.LFE0:
.size zapleft, .-zapleft
答案 2 :(得分:1)
CROPLEFT(int X,int POS) {
int mask = 1 << POS;
while (X & mask)
mask <<= 1;
return (X & (mask - 1));
}
答案 3 :(得分:0)
用以下内容替换尾随零:
x = x | (x-1);
用零替换尾随的那些:
x = x & (x+1);
编辑:Oups,似乎我误读了这个问题,上面的代码将右边的位置为零,而不是左边的位!
要将左位置零,我们需要最后的XOR运算:
y = x | (x-1);
y = y & (y+1);
y = x ^ y;
编辑2 关于起始位置POS
我们必须在第一步中将最右边的POS位清零。
y = x & (-1U<<pos);
y = y | (y-1);
y = y & (y+1);
y = x ^ y;
编辑3 如果在POS上遇到第一组零,则忽略第一组零。
如果这不回答问题,那么代码会更短,但非常像现在的rci:
y = x | ((1U<<pos)-1); // fill trailing positions with ones
y = y & (y+1); // replace trailing ones by zeroes
y = x ^ y; // modify leading bits rather than trailing ones