Input number of bytes can be increased this way: 2 input bytes =3D 3 output bytes (6 bcd digits) first bcd digit will be zer= o 3 input bytes =3D 4 output bytes (8 bcd digits) 4 input bytes =3D 5 output bytes (10 bcd digits) 5 input bytes =3D 7 output bytes (14 bcd digits) first bcd digit will be zero - quite a large number This easily verifiable using a calculator that have hex option, like Windows Calculator and others. The changed code below would work for three bytes input results in a four bytes (8 bcd digits) output. Notice the added bcd3, Byte2 and the loop control which is now 24 instead o= f 16: procedure bin3bcd4 (byte out bcd3,byte out bcd2,byte out bcd1,byte out bcd0= , Byte in bin2,Byte in bin1 ,Byte in bin0) is bcd3 =3D 0 ; added instruction bcd2 =3D 0 bcd1 =3D 0 bcd0 =3D 0 for 24 loop ; all (24) bits of bin0..bin2..bin3 - changed 16 to 24 AdjBcd(bcd0) =09 AdjBcd(bcd1) =09 AdjBcd(bcd2) AdjBcd(bcd3) ; added instruction Assembler =09 rlf bin0,f rlf bin1,f rlf bin2,f ; added instruction rlf bcd0,f rlf bcd1,f rlf bcd2,f rlf bcd3,f ; added instruction End Assembler End loop End procedure I'm not to good with C code. I would have done it in assembler, but the logic would be the same. Have a good one On Mon, May 2, 2011 at 11:21 AM, Byron Jeff wr= ote: > On Mon, May 02, 2011 at 07:14:41AM -0400, Michael Watterson wrote: >> Vasile =A0can you or someone else explain >> http://www.piclist.com/techref/piclist/jal/bin2bcd3.htm >> >> 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 >> for now, but later 9 digits from 32 bit number is useful. >> >> What you have looks far smarter than repeated division & Mod by 10. >> >> 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 > 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. =A0Then > 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 value= s > below are hex): > > Low: 0F which converts 15 in BCD > Hi: =A010 which converts 16 in BCD > > 2. Now add them together: > > =A015 > +16 > --- > =A02B > > 3. Note that the low nybble isn't BCD. Compensate by adding 6: > > =A02B > +06 > --- > =A031 > > All done. > > Now let's try the same on a 16 bit unsigned. We need 5 BCD digits, so eac= h > binary nybble (4 of them) needs 3 bytes each, though most parts of each w= ill 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: > > =A000015 > =A000240 > =A003840 > +61440 > ------ > =A064ED5 > > 3. Compensate for non BCD digits from right to left by adding a 6 in the > appropriate column for each: > > =A064ED5 > +00060 > ------ > =A064F35 > +00600 > ------ > =A065535 > > 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 ro= ws > of 8 digits each: > > table4096: > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,0,0,0,0,0 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,0,4,0,9,6 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,0,8,1,9,2 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,1,2,2,8,8 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,1,6,3,8,4 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,2,0,4,8,0 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,2,4,5,7,6 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,2,8,6,7,2 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,3,2,7,6,8 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,3,6,8,6,4 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,4,0,9,6,0 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,4,5,0,9,6 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,4,9,1,5,2 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,5,3,2,4,8 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,5,7,3,4,4 > =A0 =A0 =A0 =A0dt =A0 =A0 =A00,0,0,6,1,4,4,0 > > Now that I think about it, there's really no need to have separate storag= e > for each converted digits. Just keep a running sum of the digits converte= d > so far, and add the new digits directly to them. Something like > > =A000015 > +00240 > ------ > =A000255 > +03840 > ------ > =A003A95 > +61440 > ------ > =A064ED5 > > 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 > >> > >> -- >> http://www.piclist.com PIC/SX FAQ & list archive >> View/change your membership options at >> http://mailman.mit.edu/mailman/listinfo/piclist > > -- > Byron A. Jeff > Department Chair: IT/CS/CNET > College of Information and Mathematical Sciences > Clayton State University > http://cims.clayton.edu/bjeff > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist > --=20 http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .