【问题标题】:MATLAB converting a vector of values to uint32MATLAB 将值向量转换为 uint32
【发布时间】:2009-07-14 21:15:35
【问题描述】:

我有一个包含值 0、1、2 和 3 的向量。我想要做的是从从该向量中提取的每组 16 个元素中取出低两位,并将它们全部附加在一起以获得一个 uint32。有谁知道一个简单的方法来做到这一点?

后续:如果向量中的元素个数不是16的整数倍怎么办?

【问题讨论】:

  • 只是好奇,但这是一个隐写术项目吗?
  • 不。数字通信。我正在使用 modulate 函数和 qammod 对象。我有一堆 uint32,我想使用 qpsk(或任何 M-QAM)进行调制。除非您了解调制方案,否则有点难以解释。
  • 如果 nWord 不是整数,我想这意味着在 v 的末尾有一个部分 32 位字?我想你可以使用 nWord = floor(size(v,1)/16),从 v 中提取前 16*nWord 值,然后将其余的值排队等待下一批输入的处理。

标签: matlab vector bit-manipulation data-conversion unsigned-integer


【解决方案1】:

这是一个矢量化版本:

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

【讨论】:

  • 矢量化非常聪明,我不会想到的。您可以(稍微)通过使用 sum(reshape(v, [16 nWord]) .* repmat(2.^(30:(-2):0)',[1 nWord])) 来优化它。这避免了bitget。
  • 好吧,使用矩阵乘法的另一个优化: uint32(reshape(v, [16 nWord])' * (2.^(30:(-2):0)'))' (我也将演员表添加到 uint32)。正如 schnaader 在他/她的回答中所说,如果您的向量是 LSB 到 MSB,请将指数向量更改为 0:2:30。
【解决方案2】:

为了完善 Jacob 在他的 answer 和 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)');

【讨论】:

    【解决方案3】:

    我认为你应该看看bitgetbitshift。应该有可能是这样的(伪matlab代码,因为我很久没用matlab了):

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

    请注意,这将为您提供最高位中第一个向量的最后一位,因此您可能希望将 i 从 16 降为 1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-30
      • 2011-09-23
      相关资源
      最近更新 更多