MATLAB конвертирует вектор значений в uint32 - PullRequest
3 голосов
/ 15 июля 2009

У меня есть вектор, содержащий значения 0, 1, 2 и 3. Я хочу взять два младших бита из каждого набора из 16 элементов, взятых из этого вектора, и сложить их все вместе, чтобы получить один uint32. Кто-нибудь знает простой способ сделать это?

Продолжение: что, если число элементов в векторе не кратно 16?

Ответы [ 3 ]

6 голосов
/ 15 июля 2009

Вот векторизованная версия:

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 ]))
3 голосов
/ 15 июля 2009

Чтобы уточнить, что было предложено Джейкобом в его ответе и mtrw в его комментарии, вот самая краткая версия, которую я могу придумать (учитывая переменную 1 на N vec, содержащую значения От 0 до 3):

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

Это обрабатывает первый элемент в массиве как младший бит в результате. Чтобы рассматривать первый элемент как наиболее значимый бит, используйте следующее:

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

РЕДАКТИРОВАТЬ: Это обращается к новой редакции вопроса ...

Если число элементов в вашем векторе не кратно 16, то последняя серия чисел, которые вы извлечете из нее, будет иметь менее 16 значений. Вы, вероятно, захотите дополнить старшие биты ряда нулями, чтобы сделать его вектором из 16 элементов. В зависимости от того, является ли первый элемент в серии младшим значащим битом (LSB) или старшим значащим битом (MSB), вы закончите заполнение ряда по-разному:

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

Если вы хотите обработать весь вектор сразу, вот как вы это сделаете (с любым необходимым добавлением нуля) для случая, когда vec(1) является 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)');

и когда 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)');
0 голосов
/ 15 июля 2009

Я думаю, вам стоит взглянуть на bitget и bithift . Должно быть возможно что-то вроде этого (псевдоматлабный код, так как я давно не работал с Matlab):

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

Обратите внимание, что это даст вам последние биты первого вектора в старших битах, так что вы можете уменьшить i с 16 до 1 вместо

...