2017-03-29 23 views
1

我想实现将通过二进制表示添加两个整数的代码。在二进制表示中添加两个整数

例如:

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 

我在哪里犯了一个错误?

+0

不是应该'S =零(M + 1,1)' – Suever

+0

耶,我看到它,它是错字,但仍具有一些缺陷 –

+2

'str2double(num2cell(dec2bin(bin2dec(num2str(a))+ bin2dec(num2str(b)))))' –

回答

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

使用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 
2

此问题已在2011年的问题MATLAB Answers中讨论过。我想提2个解决方案:

  • 如果有通讯系统工具箱,你可以使用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

既然你在处理二进制数,为什么不使用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