Question

J'ai un vecteur contenant les valeurs 0, 1, 2 et 3. Ce que je veux faire, c'est prendre les deux bits inférieurs de chaque ensemble de 16 éléments tirés de ce vecteur et les ajouter tous ensemble pour obtenir un Uint32. Quelqu'un connaît un moyen facile de faire cela?

Suivi: Et si le nombre d'éléments dans le vecteur n'est pas un multiple entier de 16?

Était-ce utile?

La solution

Voici une version vectorisée:

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

Autres conseils

Pour affiner ce qui a été suggéré par Jacob dans son réponse Et mtrw dans son commentaire, voici la version la plus succincte que je puisse trouver (compte tenu d'une variable 1 par n vec contenant les valeurs 0 à 3):

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

Cela traite le premier élément du tableau comme le bit le moins significatif dans le résultat. Pour traiter le premier élément comme le bit le plus significatif, utilisez ce qui suit:

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

ÉDITER: Cela aborde la nouvelle révision de la question ...

Si le nombre d'éléments dans votre vecteur n'est pas un multiple de 16, alors la dernière série de nombres que vous en extraire aura moins de 16 valeurs. Vous voudrez probablement remplir les bits les plus élevés de la série avec des zéros pour en faire un vecteur à 16 éléments. Selon que le premier élément de la série soit le bit le moins significatif (LSB) ou le bit le plus significatif (MSB), vous finirez par rembourser la série différemment:

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 vous souhaitez traiter l'intégralité du vecteur en même temps, voici comment vous le feriez (avec tout le nord de pading nécessaire inclus) pour l'affaire lorsque vec(1) est le 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)');

et quand vec(1) est le 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)');

Je pense que tu devrais jeter un œil bitget et binancing. Il devrait être possible d'être quelque chose comme ça (code pseudo-matlab car je n'ai pas travaillé avec Matlab depuis longtemps):

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

Notez que cela vous donnera les derniers morceaux du premier vecteur dans les bits les plus élevés, vous voudrez peut-être descendre de 16 à 1 à la place

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top