输入:
arbitrary bitset, e.g. bit positions 012345
arbitrary bit mask, e.g. (x=1) xx0x0x
输出:
xx0x1x2345
也就是说,我希望将bitset的第一位放在掩码的前0位。同样,第二个位置于掩码的第二个0中。
示例:
mask = 1001001
bits = 1101
result = 1111011
我知道这可以通过循环完成,但我想主要使用位操作。我知道你可以只使用掩码和位运算符来执行任意位置换。由于输入掩码将被多次使用,我愿意花费大量时间来设置置换掩码。
编辑:我查看了http://graphics.stanford.edu/~seander/bithacks.html和http://www.hackersdelight.org/HDcode.htm的算法,但还没有找到确切的方法。
答案 0 :(得分:1)
我认为012345打算成为BITSET,他使用0..5来表示0和1的混合。
但是,这似乎不是一个按位操作。我坚持一个循环..
答案 1 :(得分:1)
如果我没有弄错,你需要一个函数f(位掩码,位集),如:
f(0b00110101,0b000ABCDE)= 0bABC11D1E1
其中第一个参数(位掩码)相对固定。
我认为你必须遍历位掩码,并且在该循环内部你可以使用按位运算。当然你可以预先编译位掩码并保持0的位置,如{1,3,6,7,...},并通过循环遍历序列来保存一些周期。
答案 2 :(得分:0)
答案 3 :(得分:0)
我认为您尝试实现的效果是(使用您的示例数据,但有些不同地放置信息):
bitmask = 1001001
bitset = 11 01
result = 1111011
现在,如果我们将其描述为从右到左(最低有效位优先)工作,那么bitset的最后1意味着需要设置最右边的位掩码0。 bitset中的零表示位掩码的下一个0不变;下一个意味着第三个零转换为一个;最重要的1意味着第四个零被转换为1.由于bitset中没有更多的,所以这是最后的改变。请注意,这种算法的公式避免了bitset或bitmask中有多少位的问题 - 而从左到右的解释会导致很大的问题。
让我们回顾一下其他一些例子:
bitmask = 1001001 1001001 1100011000 0000000101001001
bitset = 11 00 10 00 110 010 11100 1 00 11
result = 1111001 1101001 1111011010 0011100111001111
bitmask = 01001101 01001011 11000010 0000000011111111
bitset = 1 10 1 1 10 1 110 1 1101
result = 11101111 11101111 11011011 0000110111111111
如果这种解释是正确的,那么bitset的含义会根据位掩码而变化。如果位掩码和位集限制为8位,那么对于每个位集,您可能最终计算出一组256个值,这些值可以与原始位掩码值进行“或”运算以产生结果。另一方面,您可以轻松地将结果计算为要对主数据进行OR运算的值。
答案 4 :(得分:0)
大多数交错位或通用聚合位功能都是循环的,但是以一种非显而易见的方式。
即使计数位功能也有O(log2(整数位))复杂度。
因此,如果您愿意接受O(掩码中的零数)循环,那么这可能是您最好的选择。 (无论如何,你必须有一个没有原生insert bits instruction的算法。):
unsigned blah(unsigned bitmask, unsigned bits_to_insert)
{
unsigned insertion_bitmask= ~bitmask;
while (insertion_bitmask)
{
unsigned bit_position_to_insert= insertion_bitmask & -insertion_bitmask;
unsigned current_bit= bits_to_insert & 1;
unsigned bit_to_insert_into_mask= (-current_bit) & bit_position_to_insert;
bitmask|= bit_to_insert_into_mask;
bits_to_insert>>= 1;
insertion_bitmask&= insertion_bitmask - 1;
}
return bitmask;
}