二进制数向量的高效位改组

Efficient bit shuffling of vector of binary numbers

我记录了包含位序列向量的数据,我想有效地重新排列这些数据。数据向量中的一个值可能如下所示:

bit0, bit1, bit2, ... bit7

我想将这个位序列重新排列成这个顺序:

bit0, bit7, bit1, bit6, bit2, bit5, bit3, bit4

如果我只有一个值,这将通过以下方式很好地工作:

sum(uint32(bitset(0,1:8,bitget(uint32(X), [1 8 2 7 3 6 4 5]))))

不幸的是,bitset 和 bitget 无法处理位序列向量。由于我有一个相当大的数据集,我对有效的解决方案很感兴趣。

任何帮助将不胜感激,谢谢!

我不知道我是否会把问题弄错,但这不是可以通过索引包裹到 cellfun 中来解决吗?

%// example data
BIN{1} = dec2bin(84,8)
BIN{2} = dec2bin(42,8)

%// pattern and reordering
pattern = [1 8 2 7 3 6 4 5];
output = cellfun(@(x) x(pattern), BIN, 'uni', 0)

或者您输入的格式和期望的输出是什么?


BIN = 

    '01010100'    '00101010'


output = 

    '00100110'    '00011001'

dec2binbin2dec可以处理向量,你可以一次输入所有数字并置换矩阵:

input=1:23;
pattern = [1 8 2 7 3 6 4 5];
bit=dec2bin(input(:),numel(pattern));
if size(bit,2)>numel(pattern)
    warning('input numbers to large for pattern, leading bits will be cut off')
end
output=bin2dec(bit(:,pattern));

如果可用,我会使用 de2bibi2de

最有效的方法可能是像您在问题中所做的那样使用 bitgetbitset,尽管您只需要一个 8 位整数。假设你有一个 uint8 数组 X 来描述你记录的数据(对于下面的例子,X = uint8([169;5]),没有特别的原因。我们可以通过创建一个有用的匿名函数来检查这些位:

>> dispbits = @(W) arrayfun(@(X) disp(bitget(X,1:8)),W)
>> dispbits = 

@(W)arrayfun(@(X)disp(bitget(X,1:8)),W)
>> dispbits(X)
    1    0    0    1    0    1    0    1

    1    0    1    0    0    0    0    0

并假设您有一些模式 pattern,您希望根据该模式对存储在该整数向量中的位进行重新排序:

>> pattern

pattern =

     1     8     2     7     3     6     4     5

您可以使用 arrayfunfind 根据 pattern 对位重新排序:

Y = arrayfun(@(X) uint8(sum(bitset(uint8(0),find(bitget(X,pattern))))), X)

Y =

   99
   17

我们得到了有效存储在 8 位整数向量中的所需答案:

>> class(Y)

ans =

uint8

>> dispbits(Y)
    1    1    0    0    0    1    1    0

    1    0    0    0    1    0    0    0