>
> On Sun, 14 Feb 2010, Josh Koffman wrote:
>
>
>> On Tue, Feb 9, 2010 at 12:36 AM, Josh Koffman <
@spam@joshybearKILLspam
gmail.com> wrote:
>>
>>> Hi all. I'm thinking of a project where I'll have a 9 bit binary
>>> number, and I'll want to display it on a 3 digit 7 segment display. To
>>> do this I'll need to extract the hundreds, tens, and ones digits from
>>> the number. The PICList.org website has an 8 bit version to do this
>>> (
http://www.piclist.org/techref/microchip/math/radix/b2oth-8b3d-jsv.htm).
>>> Has anyone seen a 9 bit version (or a higher bit version that's easily
>>> foolable, I guess up to 16 bit would be easy)?
>>>
>> I've decided to limit myself to an input of 255 for now. Once I get
>> that working I'll move on to getting the extra bit to work and adding
>> on to my existing 8 bit to H,T,O.
>>
>> I'm starting to work with the routine linked to in my original email.
>> I'm rewriting it in my own style to make sure I understand how it
>> works. I got the hundreds conversion (at least I think I understand
>> it). I must admit I've lost the scent on the tens and ones. The author
>> notes that they should be run together, but I can't see why. In fact
>> it seems to me that if they are run together then the routine won't
>> output the number of tens anywhere. Also shouldn't the hundreds
>> routine feed into the tens routine?
>>
>> Man I'm confused. Continuing web searching, but any help would be appreciated.
>>
> 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
>