Hi I need to convert a hex value (0 to 270Fh) or with negatv 2s complement D8F1h to 270Fh to the its four decimal digits exple 1234 (which is 4D2h) to 1, 2 , 3 and 4 this is for generating ASCII or so characters... in C++ it gives someting like : #include <stdio.h> #include <stdlib.h> int m,c,d,u; double Val; char string[20]; int main(int argc, char* argv[]) { do{ printf("\nValeur ? "); gets(string); Val= atof( string); m=(int)(Val/1000); c=(int)((Val-1000*m)/100); d=(int)((Val-1000*m-100*c)/10); u=Val-1000*m-100*c-10*d; printf("Conversion : m=%d c=%d d=%d u=%d", m,c,d,u); } while (Val !=-1); return 0; } BUT I NEED to write it for fixed point DSP (TMS320F24x), as short as possible it has 32 bit accu, multiplication... and no division ! any ideas ? thanks in advance Lotfi
convert hex to dec four digits on 320F24x DSP
Started by ●May 24, 2004
Reply by ●May 24, 20042004-05-24
Hi Lofti, I just did this with multiplies. Check out this usenet post for some ideas. I did a similar thing, but used 6553/65536 =~ 0.1 instead of 41/4096 = 0.01. Cheers, Syms. http://tinyurl.com/2wty3 "Lotfi" <llbaghli(nospam)@ifrance.com> wrote in message news:c8sfph$mdg$1@arcturus.ciril.fr...> > > BUT I NEED to write it for fixed point DSP (TMS320F24x), as short as > possible > it has 32 bit accu, multiplication... and no division ! > any ideas ? > > thanks in advance > Lotfi > >
Reply by ●May 25, 20042004-05-25
hi // Get leading digit: n *= 103; // n = (((((n << 1) + n) << 2) + n) << 3) - n; d1 = n >> 10; // Mask away the first digit n &= 1023; // Multiply the remainder by 10/2, and shift down: n += n << 2; // n = n * 5; d2 = n >> 9; printf("Conversion rapide: d=%d u=%d\n", d1, d2); but it works for 0-99 only I found on http://www.cs.uiowa.edu/~jones/bcd/decimal.html if (n < 0) { putchar( '-' ); n = -n; } d1 = (n>>4) & 0xF; d2 = (n>>8) & 0xF; d3 = (n>>12) & 0xF; d0 = 6*(d3 + d2 + d1) + (n & 0xF); q = (d0 * 0x19A) >> 12; d0 = d0 - 10*q; d1 = q + 9*d3 + 5*d2 + d1; q = (d1 * 0x19A) >> 12; d1 = d1 - 10*q; d2 = q + 2*d2; q = (d2 * 0x1A) >> 8; d2 = d2 % 10; d3 = q + 4*d3; d4 = (d3 * 0x1A) >> 8; d3 = d3 - 10*d4; printf("Conversion rapide: dm=%d m=%d c=%d d=%d u=%d\n", d4, d3, d2, d1, d0); but it is too long with lot of *.... :-(
Reply by ●May 25, 20042004-05-25
Lofti, Did you read this bit?>>>>>I'm really partial to using the 1/100 approximation 41 / 4096. With inputs of more than 3 digits, this can result in a wrong answer, but since it will be too large, the subsequent back-multiplication and subtraction will detect it easily, and allow a fixup based on the carry flag. The intermediate radix-100 numbers can then be split into 2 digits using 103 / 1024 as an 'exact approximation' to 1/10 over the 0..99 range. <<<<< cheers, Syms.
Reply by ●May 25, 20042004-05-25
>>>>> "Symon" == Symon <symon_brewer@hotmail.com> writes:Symon> Lofti, Symon> Did you read this bit? >>>>>> Symon> I'm really partial to using the 1/100 approximation 41 / 4096. Symon> With inputs of more than 3 digits, this can result in a wrong answer, Symon> but since it will be too large, the subsequent back-multiplication and Symon> subtraction will detect it easily, and allow a fixup based on the carry Symon> flag. It is possible to compute floor(n/d) exactly by using one multiplication and maybe some shifts. So if you want floor(n/100) using a 16-bit word-width, you can do something like floor(n/d) = floor(m*n/2^p) = floor((m*n/2^W)/2^s) where W is the word width, m is the magic number and s is a shift. For a 16-bit word (W = 16), m = 5243 and s = 3. For a division by 10, m = 26215 and s = 2. If d = 100 and W = 12, m = 1311, s = 5. See Hacker's Delight for the proof and algorithm. Ray
Reply by ●May 26, 20042004-05-26
Thank you for your answer ok to find the right couple (M and s), I have to minimise the function : f(M,s)= M/2^s/2^16 - 1/d for 16 bit data where d=10, 100 or 1000 in my case. I 'll use mathematica or so, but I don't know if the optimizer works with integer values ??? will try and see. Afterwards, I 'll write the routine to extract the decimal digits exple for 1234 it will extract 1, 2, 3 and 4. then display it on my LCD... I am thinking of divising the work in two similar, n (check its 2 digits [thank to your 10 formula]) and n/100 [thank to your 100 formula] (check its 2 digits [thank to your 10 formula]) yours sincerely Lotfi "Raymond Toy" <toy@rtp.ericsson.se> a �crit dans le message news: sxd1xl8gvwn.fsf@edgedsp4.rtp.ericsson.se...> >>>>> "Symon" == Symon <symon_brewer@hotmail.com> writes: > > Symon> Lofti, > Symon> Did you read this bit? > >>>>>> > Symon> I'm really partial to using the 1/100 approximation 41 / 4096. > > Symon> With inputs of more than 3 digits, this can result in a wronganswer,> Symon> but since it will be too large, the subsequentback-multiplication and> Symon> subtraction will detect it easily, and allow a fixup based onthe carry> Symon> flag. > > It is possible to compute floor(n/d) exactly by using one > multiplication and maybe some shifts. So if you want floor(n/100) > using a 16-bit word-width, you can do something like > > floor(n/d) = floor(m*n/2^p) > > = floor((m*n/2^W)/2^s) > > where W is the word width, m is the magic number and s is a shift. > > For a 16-bit word (W = 16), m = 5243 and s = 3. > > For a division by 10, m = 26215 and s = 2. > > If d = 100 and W = 12, m = 1311, s = 5. > > See Hacker's Delight for the proof and algorithm. > > Ray
Reply by ●May 26, 20042004-05-26
Hi just with excel I computed the best Magic numbers (round up to have positive error) here are my results for d=10, 100 and 1000 s 2^s m0 m 1/10 reste 3 8 52428.8 52429.00 0.10000038 3.8146973E-07 1/100 5242.88 5243.00 0.01000023 2.2888184E-07 1/1000 8388.608 8389.00 0.00100005 4.6730042E-08 here is the excel file :-)
Reply by ●May 26, 20042004-05-26
Lotfi wrote: ...> f(M,s)= M/2^s/2^16 - 1/dM/2^s/2^16 = (M/2^s)/2^16 = M/2^(s+16). Is that what you mean? ... Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
Reply by ●May 26, 20042004-05-26
the best routine :-)) to extract the numbers int m,c,d,u; int Magic, s; double Val; // floor 16 bits unsigned short ns=Val; // here the entry point int W=16; m=0; c=0; d=0; u=0; if (ns>32767) {printf("Attention n�gatif "); ns=-ns; } Magic=8389; s=7; // d=1000 m=floor((Magic*ns>>W)>>s); // if (m>10) alors d�passement affichage ns-=1000*m; Magic=5243; s=3; // d=100 c=floor((Magic*ns>>W)>>s); ns-=100*c; Magic=52429; s=3; // d=10 d=floor((Magic*ns>>W)>>s); u=ns-10*d; printf("Conversion magic number : m=%d c=%d d=%d u=%d\n", m,c,d,u);
Reply by ●May 26, 20042004-05-26
"Jerry Avins" <jya@ieee.org> a �crit dans le message news: 40b4bcd5$0$3124$61fed72c@news.rcn.com...> Lotfi wrote: > > ... > > > f(M,s)= M/2^s/2^16 - 1/d > > M/2^s/2^16 = (M/2^s)/2^16 = M/2^(s+16). Is that what you mean? >forget it, I made an excel file that simply calculates the magic numbers... www.baghli.com/dl/magic.xls bye