On Mon, May 02, 2011 at 07:14:41AM -0400, Michael Watterson wrote: > Vasile can you or someone else explain > http://www.piclist.com/techref/piclist/jal/bin2bcd3.htm >=20 > Is result only up to 999 (three digits)? Most likely it's only up to 255 as that is the largest binary value that can be held in a single byte. > Unsigned up to 65535 would be good as five unpacked bytes each 0 .. 9=20 > for now, but later 9 digits from 32 bit number is useful. >=20 > What you have looks far smarter than repeated division & Mod by 10. >=20 > But I don't understand it. It looks like Vasile is shifting in bits then compensating for the difference between binary and BCD with his adjust routine. My=20 conversion technique is a bit more straightforward. It also can be extended for any number of BCD digits. The basic idea conversion is to take each of the original binary nybbles and convert them into their BCD equivalents using table lookup. Then adjust any digits that are incorrect in BCD. Let's start with a 1 byte example: 1F (which needs to be converted in BCD 31): 1. Convert each binary nybble to its equivalent BCD and put in a separate byte. Conversion by table lookup works well for this (note that all values below are hex): Low: 0F which converts 15 in BCD Hi: 10 which converts 16 in BCD 2. Now add them together: 15 +16 --- 2B 3. Note that the low nybble isn't BCD. Compensate by adding 6: 2B +06 --- 31 All done. Now let's try the same on a 16 bit unsigned. We need 5 BCD digits, so each binary nybble (4 of them) needs 3 bytes each, though most parts of each wil= l go unused. Let's try converting 0xffff (which is 65535 in BCD). 1. Convert each nybble to its binary equivalent: 0: 00015 1: 00240 (0xf0 =3D 240) 2: 03840 (0xf00 =3D 3840) 3: 61440 (0xf000 =3D 61440) 2. Add them all up: 00015 00240 03840 +61440 ------ 64ED5 3. Compensate for non BCD digits from right to left by adding a 6 in the appropriate column for each: 64ED5 +00060 ------ 64F35 +00600 ------ 65535 All done. The technique becomes more difficult as the number of digits expands because the number of BCD digits spreads across many of the BCD bytes. What you end up with is a two dimensional BCD digit table for each digit where you have to scale the digit then add the offset. For example the 4th nybble table (which is multiples of 4096) can be implemented as 16 rows of 8 digits each: table4096: dt 0,0,0,0,0,0,0,0 dt 0,0,0,0,4,0,9,6 dt 0,0,0,0,8,1,9,2 dt 0,0,0,1,2,2,8,8 dt 0,0,0,1,6,3,8,4 dt 0,0,0,2,0,4,8,0 dt 0,0,0,2,4,5,7,6 dt 0,0,0,2,8,6,7,2 dt 0,0,0,3,2,7,6,8 dt 0,0,0,3,6,8,6,4 dt 0,0,0,4,0,9,6,0 dt 0,0,0,4,5,0,9,6 dt 0,0,0,4,9,1,5,2 dt 0,0,0,5,3,2,4,8 dt 0,0,0,5,7,3,4,4 dt 0,0,0,6,1,4,4,0 =09 Now that I think about it, there's really no need to have separate storage for each converted digits. Just keep a running sum of the digits converted so far, and add the new digits directly to them. Something like 00015 +00240 ------ 00255 +03840 ------ 03A95 +61440 ------ 64ED5 Then adjust the non BCD digits. I had not thought about this type of conversion in quite a while. While this does take up table space, it's really straightforward IMHO. BAJ >=20 > --=20 > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist --=20 Byron A. Jeff Department Chair: IT/CS/CNET College of Information and Mathematical Sciences Clayton State University http://cims.clayton.edu/bjeff --=20 http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .