Pergunta

Eu tenho um vetor contendo os valores 0, 1, 2 e 3. O que eu quero fazer é pegar os dois bits inferiores de cada conjunto de 16 elementos extraídos deste vetor e anexá -los todos juntos para obter um UINT32. Alguém conhece uma maneira fácil de fazer isso?

Acompanhamento: E se o número de elementos no vetor não for um múltiplo inteiro de 16?

Foi útil?

Solução

Aqui está uma versão vetorizada:

v = floor(rand(64,1)*4);
nWord = size(v,1)/16;
sum(reshape([bitget(v,2) bitget(v,1)]',[32 nWord]).*repmat(2.^(31:(-1):0)',[1 nWord ]))

Outras dicas

Refinar o que foi sugerido por Jacob em seu responda e mtrw em seu comentário, aqui está a versão mais sucinta que eu posso criar (dada uma variável 1 por n vec contendo os valores 0 a 3):

value = uint32(vec(1:16)*4.^(0:15)');

Isso trata o primeiro elemento na matriz como o bit menos significativo no resultado. Para tratar o primeiro elemento como o bit mais significativo, use o seguinte:

value = uint32(vec(16:-1:1)*4.^(0:15)');

EDITAR: Isso aborda a nova revisão da pergunta ...

Se o número de elementos em seu vetor não for um múltiplo de 16, a última série de números que você extrairá dele terá menos de 16 valores. Você provavelmente desejará preencher os bits mais altos da série com zeros para torná-lo um vetor de 16 elementos. Dependendo se o primeiro elemento da série é o bit menos significativo (LSB) ou o mais significativo (MSB), você acabará preenchendo a série de maneira diferente:

v = [2 3 1 1 3 1 2 2];  % A sample 8-element vector
v = [v zeros(1,8)];  % If v(1) is the LSB, set the higher bits to zero
% or...
v = [zeros(1,8) v];  % If v(1) is the MSB, again set the higher bits to zero

Se você deseja processar todo o vetor de uma só vez, eis como você faria (com qualquer acalmar zero necessário) para o caso quando vec(1) é o LSB:

nValues = numel(vec);
nRem = rem(nValues,16);
vec = [vec(:) zeros(1,nRem)];  % Pad with zeroes
vec = reshape(vec,16,[])';  % Reshape to an N-by-16 matrix
values = uint32(vec*4.^(0:15)');

e quando vec(1) é o msb:

nValues = numel(vec);
nRem = rem(nValues,16);
vec = [vec(1:(nValues-nRem)) zeros(1,nRem) ...
       vec((nValues-nRem+1):nValues)];  % Pad with zeroes
vec = reshape(vec,16,[])';  % Reshape to an N-by-16 matrix
values = uint32(fliplr(vec)*4.^(0:15)');

Eu acho que você deveria dar uma olhada bitget e Desfrutamento de bits. Deveria ser possível ser algo assim (código pseudo-matlab, pois não trabalho com o MATLAB há muito tempo):

result = 0;
for i = 1:16 do
  result += bitshift(bitget(vector(i), 2:-1:1), 2);

Observe que isso lhe dará os últimos bits do primeiro vetor nos bits mais altos, então você pode descer I de 16 a 1 em vez disso

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top