On Sun, 14 Feb 2010, Josh Koffman wrote: > On Tue, Feb 9, 2010 at 12:36 AM, Josh Koffman 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 -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist