按位操作出现问题
Trouble with bitwise manipulation
好的,伙计们,我知道我想做什么,但我不知道它是否已经存在(作为一个函数或理论上)或如何表达它,所以我需要你的帮助:
- 假设我们有一个二进制数:(msb)
10101110
(lsb) - 从位 X 开始,一旦遇到第一个零位,我想将所有其他位(向左)归零。
- 尽可能快地做到这一点,所需的操作次数和 CPU 周期绝对最少
一个例子:
- 数字 = 10101110,起始位置 = 1(
- 位置 1 处的位 = 1)
- 位置++ - 位 2 = 1,继续前进
- 位置++ - 位置 3 = 1 处的位,继续前进
- 位置++ - 位在位置 4 = 0,哎呀...零遇到...现在,一切都必须归零。
因此,我们的虚函数 CROPLEFT(X,POS) 的最终结果,其中 X=10101110,POS=1,将返回00001110
。
有什么想法吗?
小菜一碟。
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指令,否则没有这样的运气来获得最高设置的位,所以你很幸运你的问题要求最低。
好吧,到底是什么:
return x & ((x ^ (x + (1UL << POS))) | ((1UL << POS) - 1))
值得一提的是,它们都用gcc-4.7 -O3编译。左边,右边是我的:(两者都使用无符号的长和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
CROPLEFT(int X,int POS) {
int mask = 1 << POS;
while (X & mask)
mask <<= 1;
return (X & (mask - 1));
}
将
尾随的零替换为 1:
x = x | (x-1);
将尾随的 1 替换为零:
x = x & (x+1);
编辑:哎呀,看来我误读了这个问题,上面的代码将正确的位归零,而不是左位!
要将左位归零,我们需要一个最终的 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
相关文章:
- 对字符串进行位操作
- 对字符数组中的元素执行逐位操作
- 逐位操作的隐式类型转换
- 如何进行特定的位操作?
- C++避免位操作完全移位
- 使用双包装器类进行位操作(C++、clang)修复性能下降问题
- 使用位操作优化检查
- 子集相关位操作
- 使用 c++ 提升库的按位操作
- 位操作和异或
- 位操作将最左侧的设置位转换为右侧交替位?
- 为什么对小于 4 个字节的整数类型的位操作会发生意外行为?
- POD 类型的原子按位操作
- 如何使用位操作在单个整数中编码和解码两个数字
- __int128的位操作
- 使用位操作会影响内存消耗?
- 按位操作出现问题
- 逐位操作和移位问题
- 有符号和无符号int、XNOR的位操作问题
- 用位操作创建字符的问题