Domanda

Ho un vettore contenente i valori 0, 1, 2 e 3. Quello che voglio fare è prendere i due bit più bassi da ciascun set di 16 elementi disegnati da questo vettore e aggiungerli tutti insieme per ottenere un UINT32. Qualcuno sa un modo semplice per farlo?

Follow-up: cosa succede se il numero di elementi nel vettore non è un multiplo intero di 16?

È stato utile?

Soluzione

Ecco una versione vettoriale:

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

Altri suggerimenti

Per perfezionare ciò che è stato suggerito da Giacobbe nel suo Rispondere E MTRW nel suo commento, ecco la versione più succinta che posso inventare (data una variabile 1 per N vec contenente i valori da 0 a 3):

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

Questo tratta il primo elemento nell'array come la punta meno significativa nel risultato. Per trattare il primo elemento come il bit più significativo, usa quanto segue:

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

MODIFICARE: Questo affronta la nuova revisione della domanda ...

Se il numero di elementi nel vettore non è un multiplo di 16, allora l'ultima serie di numeri che ti estrai avrà meno di 16 valori. Probabilmente vorrai colpire i pezzi più alti della serie con zero per renderlo un vettore a 16 elementi. A seconda che il primo elemento della serie sia il bit meno significativo (LSB) o il bit più significativo (MSB), finirai per imbottirti in modo diverso:

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 si desidera elaborare l'intero vettore tutto in una volta, ecco come lo faresti (con qualsiasi costo zero necessario) per il caso in cui il caso vec(1) è l'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) è 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)');

Penso che dovresti dare un'occhiata bitget e BiTshift. Dovrebbe essere possibile essere qualcosa del genere (codice pseudo-matlab in quanto non lavoro con Matlab da molto tempo):

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

Nota che questo ti darà gli ultimi bit del primo vettore nei pezzi più alti, quindi potresti voler scendere da 16 a 1 invece

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top