piclist 2010\02\15\064027a >
Thread: 9 bit binary to digits?
massmind.org/techref/microchip/devices.htm?key=pic
flavicon
face BY : sergio masci email (remove spam text)





On Sun, 14 Feb 2010, Josh Koffman wrote:

{Quote hidden}

lets say you want to convery the binary number 359 to ascii digits. Dont
worry that it's shown as decimal or greater than 255 for now.

So what you would normally do is look at the 100s column and take the 3
then the 10s column and take the 5 then the 1s column and take the 9. Ok
so how do we take a digit from a column on a computer. Well what we
actually do is take '1' away from that column until we get to '0' and we
count how many times we are able to do this. If we write this in pseudo
code we get:

For the 100s column

       value = 359
       count = 0

       while value >= 100 do
               value = value - 100
               count = count + 1
       done

at this point we end up with

       value = 59
       count = 3

It's important that we start with the highest column first.

For the 10s column

       count = 0

       while value >= 10 do
               value = value - 10
               count = count + 1
       done

now we end up with

       value = 9
       count = 5

Now at this point you can easily see that the '1' column is whats left in
'value'

Now to clear up the confusing bits.

decimal 359 is binary 01 0110 0111
decimal 100 is binary 00 0110 0100
decimal  10 is binary 00 0000 1010
decimal   1 is binary 00 0000 0001

decimal 300 is binary 01 0010 1100
decimal  50 is binary 00 0011 0010

When we take the 3 from the 100s (hundreds) column we are trying to
convert
binary 0100101100 to binary 0000000011.

When we take the 5 from the 10s (tens) column we are trying to convert
binary 0000110010 to binary 0000000101.

so the easiest way to do this is to repeatedly take binary 0100101100 from
binary 0101100111 (359) and count in units (binary 0000000001).

0101100111 (359) - 0001100100 (100) = 0100000011 (259) ; count = 1
0100000011 (259) - 0001100100 (100) = 0010011111 (159) ; count = 2
0010011111 (159) - 0001100100 (100) = 0000111011  (59) ; count = 3

so at this point we have converted 'value' from 0101100111 (359) to
0000111011 (59) and 'count' to 0000000011 (3)

doing the same for the 10s (tens) we get:

0000111011 (59) - 0000001010 (10) = 0000110001 (49) ; count = 1
0000110001 (49) - 0000001010 (10) = 0000100111 (39) ; count = 2
0000100111 (39) - 0000001010 (10) = 0000011101 (29) ; count = 3
0000011101 (29) - 0000001010 (10) = 0000010011 (19) ; count = 4
0000010011 (19) - 0000001010 (10) = 0000001001  (9) ; count = 5

so at this point we have converted 'value' from 0000111011 (59) to
0000001001 (9) and  'count' to 0000000101 (5)

now if we look at the pseudo code again - just the 100s (hundreds) for
now:

       value = 359
       count = 0

       while value >= 100 do
               value = value - 100
               count = count + 1
       done


we see a horrible '>=' which kind of complicates things if we are trying
to convert this pseudo code into assembly language. We can rearrange
things to make them easier like this:

       value = 359
       count = 0

       while (value - 100) > 0 do
               value = value - 100
               count = count + 1
       done

Another way to think about "X > 0" is "is X not negative". If you have
enough bits in your variables and you are using 2's complement
arithmetic (which tends to be available on most processors these days)
then this is a very easy test to make.

e.g.

0000111011 (59) - 0001100100 (100) = 1111010111 (-41)

simply by looking at the most significant bit (the left most bit) and
testing if it is a '0' or a '1' we can see if the result is positive
or zero (for bit = 0) or negative (for bit = 1).

So we can actually convert the pseudo code to

       value = 359
       count = 0

       while ((value - 100) & 512) == 0 do
               value = value - 100
               count = count + 1
       done

If we tried to do this on a variable that had only 8 bits we would be
restricting ourselves to numbers on the range -128 to +127 (because we
want to use the most significant bit for the sign. If we use 16 bits then
we increase our range to -32768 to +32767.

The above pseudo code would then become

       value = 359
       count = 0

       while ((value - 100) & 32768) == 0 do
               value = value - 100
               count = count + 1
       done

Which is really really easy to convert to PIC assembly code!

It is well worth using multiprecision arithmetic on a PIC (going from 8
bit variables to 16 bit variable) to simplify maths.

Also a very important aspect of multiprecision arithmetic on an 8 bit CPU
like the PIC is the ability to calculate addresses greater than 255!!!


I hope this helps.

Regards
Sergio Masci
<Pine.LNX.4.61.1002151408400.13156@yoda.srts.co.uk> 7bit

In reply to: <3e0a4bc41002141437p3a23315ub47747fbdb302b0b@mail.gmail.com>
See also: massmind.org/techref/microchip/devices.htm?key=pic

month overview.

new search...