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






