Leader

Tuesday 2 December 2008

Converting decimal to binary and binary to decimal

See also: Base conversion of positional number systems for other conversion functions.

Download
dec2bin2.m (decimal to binary)
bin2dec2.m (binary to decimal)

Final code
See below.

Explanation
MATLAB already contains two functions to do convert between binary and decimal (dec2bin and bin2dec) but I wanted to write my own as a learning exercise – both in scripting and to learn the actual conversion method. Looking at the code in MATLABs functions is pretty fruitless for the latter. There are a couple of difference between my scripts and MATLABs, for example my dec2bin2 function automatically buffers the output to 8 bits in the form of a vector rather than a string. Conversely my bin2dec string doesn’t require a string as an input, which is convenient for certain applications.

This code is written in a way to make the processes of conversion as clear as possible - it's all done with loops, which isn't technically the best way, but it serves a purpose here!




The conversion process itself is explained on Wikipedia. I strongly suggest reading this as it covers the mathematical processes to convert in more detail than I’m going to.



Binary -> Decimal


The process to convert binary to decimal is very simple. Each digit is multiplied by 2^i. “i” being the digits position in the sequence. Remember binary is read from right to left and the first position is 0!


For example for the binary string “0 1 1”.

1 is the first digit and its position is 0, the second digit is 1 and its position is 1, the third digit is 0 and its position is 2. The value of the string in decimal is the sum of the powers:

(0*2^2) + (1*2^1) + (1*2^0) = 3


For the binary string “1 1 0 1 0”


(1*2^4) + (1*2^3) + (0*2^2) + (1*2^1) + (0*2^0) = 26


Simple, eh?


So to script this, all we need to do is get MATLAB to apply this process – making sure it reads in the correct direction!


binstring = '0101'
for i = 1:length(binstring);
  value(i)=str2double(binstring(i)) ...
  *(2^(length(binstring)-i));
end
dec=sum(value)

The 3rd/4th line finds the current position by finding the length of the string and subtracting i. This essentially inverts the index so the loop reads the string from left to right.

I wanted a little more flexibility in my script than the MATLAB version offers, so I added a little string management to the start of the function. The script accepts either string, integer or vector input and converts non-string input into a string. It then performs the conversion operation before converting the string to an integer output.


function dec = bin2dec2(bin)
binstring = [];
if length(bin) > 1
     for i = 1:length(bin)
          tempstring = num2str(bin(i));
          binstring = [binstring,tempstring];
     end
else
     binstring=num2str(bin);
end

Line 3 uses LENGTH to check if the input is a vector, if it is, it’s converted to a string that doesn’t contain any spaces. If the input is already a string or an integer, NUM2STR is used to convert straight to a string (note: NUM2STR on a string simply gives the string back).

The full function is:

function dec = bin2dec2(bin)
binstring = [];
if length(bin) > 1
     for i = 1:length(bin)
          tempstring = num2str(bin(i));
          binstring = [binstring,tempstring];
     end
else
     binstring=num2str(bin);
end
for i = 1:length(binstring);
     value(i)=str2double(binstring(i)) ...
     *(2^(length(binstring)-i));
end
dec=sum(value);



Decimal -> Binary


Decimal to binary conversion is even more exciting. Again the process is documented in this Wikipedia article. Essentially, the decimal is divided by 2 until the result is 0.5 or 0. If there is a remainder after each division, a 1 is added to the binary sequence, if there’s no remainder, a 0 is added. 
Reversing this sequence of 1 and 0’s gives the binary sequence.

To get MATLAB to execute this process I used a while loop. The loop continues going until it reaches a point where the result of a division by 2 is 0.5 or 0 (the end of the conversion). As it runs each division step, it check if there is a remainder or not and records a 1 or a 0 as appropriate.


i=0;
p=1;
while i == 0
     if dec/2 > 0
          if dec/2 ~= round(dec/2)
               bin(p) = 1;
          end
          if dec/2 == round(dec/2)
               bin(p) = 0;
          end
     end

     if dec/2 < 1
          bin(p) = 1;
          i = 1;
     else
          p=p+1;
          dec = floor(dec/2);
     end
end

The round command is use to test if there is a remainder. For example if dec is 15 then dec/2 = 7.5 and round(dec/2) = 8. If dec/2 and round(dec/2) aren’t equal, there must be a remainder and a 1 is added to the sequence. If they are equal, there is no remainder and 0 is added to the sequence.
After this stage the script checks if dec is still >1, if it is, it is rounded down to next integer (using FLOOR) and the loop continues. If dec is <1, i is set to 1 and the loop terminates.

The sequence is then inverted so it can be read right to left

newbin=zeros(1,length(bin));
for i = 1:length(bin)
     newbin(i) = bin((length(bin)-i)+1);
end

Note the +1 in there, this is to shift the indices so that the last one is 1 not 0. bin((length(bin)-i) when i = length(bin) tries to access bin(0), which doesn’t exist.


And finally, buffered up to 8 bits (if shorter than 8 bits) and output as a vector:

if length(bin) < 8
     bin = [zeros(1,8-length(bin)), newbin];
else
     bin = newbin;
end

The full function is:

function bin = dec2bin2(dec)
i=0;
p=1;
%calculate
while i == 0
     if dec/2 > 0
          if dec/2 ~= round(dec/2)
               bin(p) = 1;
          end
          if dec/2 == round(dec/2)
               bin(p) = 0;
          end
     end
     if dec/2 < 1
          bin(p) = 1;
          i = 1;
     else
          p=p+1;
          dec = floor(dec/2);
     end
end

% Invert
newbin=zeros(1,length(bin));
for i = 1:length(bin)
     newbin(i) = bin((length(bin)-i)+1);
end

% Buffer to 8bits
if length(bin) < 8
     bin = [zeros(1,8-length(bin)), newbin];
else
     bin = newbin;
end


3 comments:

Anonymous said...

What a cool idea for a blog MATLAB has pretty much been my life for the last 3 years.

binhddt said...

Hi.
I'm doing my Thesis about Simulation of Physical layer of HSPA+ downlink channel with MIMO.
And the problem is that I want to simulate file propagation process: such as transmit text file, or image file. The input of my program is bit sequences, and I don't know how to transform text file as well as into bit sequence.
Have you ever had experiences in this problem? Please help me.
Thanks in advanced.

binhddt said...

...as well as image file...

AdSense