我正在MATLAB中设计乘法器,但不确定如何执行二进制数乘法。例如,我想将二进制110011与二进制0011相乘。但是MATLAB给出了矩阵dimensios的错误。另外,如果我在元素号较小的MSB中附加零,它仍然不允许我相乘。我缺少任何特定的算法吗?
我不想按位进行AND。我需要执行适当的乘法,
1 1 0 0 1 1
0 0 1 1
1 1 0 0 1 1
1 1 0 0 1 1
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 1 1 0 0 1
这是我附加零的代码段。
if numel(operand1)<numel(operand2)
append=zeros(1, (numel(operand2)-numel(operand1)));
operand1=[operand1 append];
else
append=zeros(1, (numel(operand1)-numel(operand2)));
operand2=[operand2 append];
end
(PS:很抱歉,可读性很差,这是我关于stackoverflow的第一篇文章,我对格式一无所知)
答案 0 :(得分:1)
这只是众多实现中的一种。它并不意味着是最快和最明亮的。也可以将其大大缩短,但是为了显示中间步骤,我将其扩展了很多。
第1步::准备所有步骤(行)
我发现不必简单地定义一个足够大以容纳我们所有值和我们将要执行的循环移位的矩阵,而不必根据每个输入的长度在此处或那里添加零。
%% Input values
a = [ 1 1 0 0 1 1 ] ;
b = [ 1 0 1 1 ] ;
%% create all the steps
nstep = numel(b) ;
steps = bsxfun( @times , flipud(b.') , a) ;
在此阶段,您的矩阵steps
如下:
>> steps
steps =
1 1 0 0 1 1
1 1 0 0 1 1
0 0 0 0 0 0
1 1 0 0 1 1
每行代表完整向量a
乘以b
的每个元素
在对这些线求和之前,我们需要移动每条线,使其与正确的2的幂对齐。为此,我们首先在矩阵左侧填充必要的零,然后使用{{1} }:
circshift
现在,您的矩阵%% pad the matrix to prepare for the shifts
pad = zeros( nstep , nstep ) ;
mat = [pad steps] ;
%% shift the step lines
for k=2:nstep
mat(k,:) = circshift(mat(k,:),[0,-(k-1)]) ; % shift each line to the left by [k-1]
end
如下:
mat
几乎在那里,现在我们只需要对行进行求和即可得出结果。不幸的是,MATLAB没有以这种方式构建 binary 求和,因此我们必须自己实现它。我将提供2种方法,一个 loop 版本(更易读)和一个 vectorized 版本(更冷酷)。
第2步:求和
>> mat
mat =
0 0 0 0 1 1 0 0 1 1
0 0 0 1 1 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 1 1 0 0 0
请注意,循环在第2列而不是第1列处停止。这是因为我已经在左侧添加了另外一列,该列仅包含零。这样做是为了使%% [LOOP method] Do the summation
ncol = size(mat,2) ;
res = zeros( 1 , ncol ) ; % pre-allocate result line
sumline = sum(mat) ; % put sum of each column in a buffer
c = 0 ; % carry
for k=ncol:-1:2 % we process the column from right to left
s = sumline(k)+c ; % sum of the column [k] plus the carry
res(k) = mod( s , 2 ) ; % result for this column
c = floor(s/2) ; % carry value for the next column
end
% now we are almost finished but there may be value left in the carry
res(1) = c % set the (MSb) on the left
变量具有足够的列以容纳进位(如果它不为null)。
以下是(第2步的)更紧凑的版本,但是它将给出完全相同的结果:
res
您去了,很长的帖子,对不起,但是我想详细说明步骤。如果仅使用代码,则可以将其压缩为简短函数:
%% [Vectorised method] ... just as good but more cryptic
sumline = sum(mat) ; % put sum of each column in a buffer
carrytmp = floor(sumline/2) ; % calculate all the "carry" values (1/2)
carry = carrytmp + circshift( carrytmp, [0,-1] ) ; % calculate all the "carry" values (2/2)
tsum = sumline + circshift( carry , [0,-1] ) ; % total sum
res = mod( tsum , 2 ) ; % final result