Pregunta

Tengo un vector que contiene los valores 0, 1, 2 y 3. Lo que quiero hacer es tomar los dos bits inferiores de cada conjunto de 16 elementos extraídos de este vector y agregarlos todos juntos para obtener un UINT32. ¿Alguien sabe una manera fácil de hacer esto?

Seguimiento: ¿Qué pasa si el número de elementos en el vector no es un múltiplo entero de 16?

¿Fue útil?

Solución

Aquí hay una versión vectorizada:

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 ]))

Otros consejos

Para refinar lo sugerido por Jacob en su responder Y MTRW en su comentario, aquí está la versión más sucinta que puedo encontrar (dada una variable 1 por N vec que contiene los valores 0 a 3):

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

Esto trata el primer elemento en la matriz como el bit menos significativo en el resultado. Para tratar el primer elemento como el bit más significativo, use lo siguiente:

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

EDITAR: Esto aborda la nueva revisión de la pregunta ...

Si el número de elementos en su vector no es un múltiplo de 16, entonces la última serie de números que extrae tendrá menos de 16 valores. Es probable que desee rellenar los bits más altos de la serie con ceros para que sea un vector de 16 elementos. Dependiendo de si el primer elemento de la serie es el bit menos significativo (LSB) o el bit más significativo (MSB), terminará acolchando la serie de manera 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

Si desea procesar todo el vector a la vez, así es como lo haría (con cualquier juego cero necesario incluido) para el caso cuando vec(1) es el 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)');

y cuando vec(1) es el 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)');

Creo que deberías echar un vistazo a bitget y desplazamiento de bits. Debería ser posible ser algo como esto (código pseudo-matlab ya que no he trabajado con Matlab durante mucho tiempo):

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

Tenga en cuenta que esto le dará los últimos bits del primer vector en los bits más altos, por lo que es posible que desee descender I de 16 a 1 en su lugar

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top