以二进制表示形式添加两个整数

时间:2017-03-29 13:38:07

标签: matlab vector binary sum integer

我想实现代码,它将通过二进制表示法添加两个整数。

例如:

a = [1 1 1 0];

b = [1 0 1 1];

所以我实现了以下算法:

function s=add_binary(a,b)
  m=length(a);
  s=zeros(m+1,0);
  n=length(a);
  c=0;
  for ii=n:-1:1
    d=floor((a(ii)+b(ii)+c)/2);
    s(ii)=a(ii)+b(ii)+c-2*d;
    c=d;          
  end
  s(1)=c; 
end

但是,它会返回结果:

s=add_binary(a,b)

s =

     1     0     0     1

此处左侧应该有一个额外的1,以便显示:

1 1 0 0 1

我在哪里犯了错误?

4 个答案:

答案 0 :(得分:2)

这是我的解决方案

function s=add_binary(a,b)
m=length(a);
s=zeros(m+1,1);
n=length(a);
c=0;
for ii=n:-1:1
    d=floor((a(ii)+b(ii)+c)/2);
   s(ii+1)=a(ii)+b(ii)+c-2*d;
   c=d;
 end
s(1)=c;
s=s';


end

>> s=add_binary(a,b)

s =

     1     1     0     0     1

答案 1 :(得分:2)

2011年MATLAB Answers的问题讨论了这个问题。我想再提两个解决方案:

  • 如果您有通讯系统工具箱,则可以使用bi2dede2bi

    de2bi(bi2de(a,'left-msb') + bi2de(b,'left-msb'),'left-msb')
    
  • 如果"数字"在输入中已知(且合理),一种解决方案可以是在一些数据结构中存储所有可能的输入组合,这将有助于快速访问。一个这样的例子是MapN class(虽然它可以很容易地用常规数字数组完成)。我将提供一个小例子来展示这个想法(包括一个基准):

    function allResults = q43095156(allResults)
      if nargin == 0 
      % Let's store all combinations of 8 binary digits:
      in = uint8(0:255);
      out = uint16(in)+uint16(in.');
      outB = logical(de2bi(out(:),'left-msb'));
      [in1,in2] = meshgrid(in,in);
      allResults = MapN(...
         num2cell([num2cell(in1(:),2),num2cell(in2(:),2)],2),...
         num2cell(outB,2));
      end
      benchmark(allResults);
    end
    
    function benchmark(allResults)
      rng(43095156);
      a = logical(randi([0 1],10,8,'uint8'));
      b = logical(randi([0 1],10,8,'uint8'));
      % Test:
      R{5} = de2bi(bi2de(a,'left-msb') + bi2de(b,'left-msb'),'left-msb');
      R{4} = add_a_bunch_gnovice(a,b);
      R{3} = add_a_bunch_Sardar(a,b);
      R{2} = add_a_bunch_dato(a,b);
      R{1} = getFromMap(a, b, allResults);
      assert(isequal(R{:}));
      % Benchmark:
      a = logical(randi([0 1],1000,8,'uint8'));
      b = logical(randi([0 1],1000,8,'uint8'));
      fprintf(1,'\nSardar''s method:\t%f',timeit(@() add_a_bunch_Sardar(a, b) ));
      fprintf(1,'\nDev-iL''s method:\t%f',timeit(@() getFromMap(a, b, allResults) ));
      fprintf(1,'\ngnovice''s method:\t%f',timeit(@() add_a_bunch_gnovice(a, b) ));
      fprintf(1,'\ndato''s method:\t\t%f',timeit(@() add_a_bunch_dato(a, b) ));
      fprintf(1,'\nbi2de method:\t\t%f',timeit(@() de2bi(bi2de(a,'left-msb') + bi2de(b,'left-msb'),'left-msb')));
    end
    
    function out = getFromMap(a,b,map)
    out = cell2mat(values(map, num2cell([ num2cell(bi2de(a,'left-msb'),2),...
                                          num2cell(bi2de(b,'left-msb'),2)],2)));
    end
    
    function out = add_a_bunch_gnovice(a,b)
      out = zeros(size(a)+[0,1],'logical');
      for ind1 = 1:size(a,1)
        out(ind1,:) = add_binary_gnovice(a(ind1,:), b(ind1,:));
      end
    end
    
    
    function out = add_a_bunch_Sardar(a,b)
      out = zeros(size(a)+[0,1],'logical');
      for ind1 = 1:size(a,1)
        out(ind1,:) = add_binary_Sardar(a(ind1,:), b(ind1,:));
      end
    end
    
    function out = add_a_bunch_dato(a,b)
      out = zeros(size(a)+[0,1],'logical');
      for ind1 = 1:size(a,1)
        out(ind1,:) = add_binary_dato(a(ind1,:), b(ind1,:));
      end
    end
    
    function s = add_binary_gnovice(a, b)
      a = [0 a];
      b = [0 b];
      c = a&b;
      while any(c)
        b = xor(a, b);
        a = circshift(c, -1);
        c = a&b;
      end
      s = a+b;
    end
    
    function s = add_binary_Sardar(a,b)
      s = logical(str2double(num2cell(dec2bin(bin2dec(num2str(a)) +...
                                              bin2dec(num2str(b)), numel(a)+1))));
    end
    
    function s = add_binary_dato(a,b)
      m = length(a);
      s = zeros(m+1,1);
      n = length(a);
      c = 0;
      for ii = n:-1:1
        d = floor((a(ii)+b(ii)+c)/2);
        s(ii+1) = a(ii)+b(ii)+c-2*d;
        c = d;
      end
      s(1) = c;
      s = logical(s.');
    end
    

    我的x64 MATLAB R2017a @ Win10的结果是:

    Sardar's method:    0.336414
    Dev-iL's method:    0.061656
    gnovice's method:   0.022031
    dato's method:      0.002123
    bi2de method:       0.000356
    

    所以这应该让我们知道哪些方法更快(除非我搞砸了包装函数)...

    如果总和的计算是一些其他更昂贵的操作,那么MapN方法的优势将是显而易见的。

答案 2 :(得分:2)

由于您正在处理二进制数,为什么不使用logical operators

function s = add_binary(a, b)
  a = [0 a];
  b = [0 b];
  c = a&b;
  while any(c)
    b = xor(a, b);
    a = circshift(c, -1);
    c = a&b;
  end
  s = a+b;
end

测试:

>> a = randi([0 1], [1 6])
a =
     0     1     0     1     0     1
>> b = randi([0 1], [1 6])
b =
     1     1     0     0     0     1
>> s = add_binary(a, b)
s =
     1     0     0     0     1     1     0

答案 3 :(得分:1)

使用num2strab转换为字符串,然后使用bin2dec将其转换为小数。然后添加它们并使用dec2bin将总和转换回二进制。使用num2cell拆分字符串,最后使用str2double获得所需的结果。

s=str2double(num2cell(dec2bin(bin2dec(num2str(a))+bin2dec(num2‌​str(b)))))

% Output for given a and b
%---------------------------
% s = 
%   1     1     0     0     1