Reply by Lotfi June 1, 20042004-06-01
solved the errors, the right code is :
and it works fine :-)

; Convertit un "Word" hexa en "4 chars D�cimaux + signe"
ConvDec .macro Var
   LACC Var
   BCND positif?, GEQ
   ZAC
   SUB  Var
   SACL Var
   LACC #02Dh
   B  evitneg?
positif?
   LACC #02Bh
evitneg?
   SACL  signe
    CLRC    SXM             ; pas de sign extension
;   SPM   0       ;PM=00, no shift after multiplication
;   Magic=8389; s=7;  // d=1000
;   m=floor((Magic*ns>>W)>>s);
   LT  M8389
   MPY   Var
   SPH  tmp
   LACC tmp,9  ;16-7=9
   SACH  tmp   ;ie 7 LSR
;  ici on aurait du checker le d�passement de m>9!
;   ns-=1000*m;
   LACC Var
   LT  tmp
   MPY   #1000
   SPAC     ;Subtract PREG from ACC
   SACL Var
   LACC tmp
   ADD  #030h  ; table de charact�res : chiffres
   SACL  millier   ; ecrit char : millier
;    Magic=5243; s=3;            // d=100
;    c=floor((Magic*ns>>W)>>s);
   LT  M5243
   MPY   Var
   SPH  tmp
   LACC tmp,13  ;16-3=13
   SACH  tmp   ;ie 3 LSR
;   ns-=100*c;
   LACC Var
   LT  tmp
   MPY   #100
   SPAC     ;Subtract PREG from ACC
   SACL Var
   LACC tmp
   ADD  #030h  ; table de charact�res : chiffres
   SACL  centaine   ; ecrit char : centaine
;   Magic=52429; s=3;           // d=10
;    d=floor((Magic*ns>>W)>>s);
   LT  M52429
   MPYU   Var  ;MPY unsigned
   SPH  tmp
   LACC tmp,13  ;16-3=13
   SACH  tmp   ;ie 3 LSR
;   ns-=10*m = u
   LACC Var
   LT  tmp
   MPY   #10
   SPAC     ;Subtract PREG from ACC
   SACL Var
   LACC tmp
   ADD  #030h  ; table de charact�res : chiffres
   SACL  dizaine   ; ecrit char : dizaine
   LACC Var
   ADD  #030h  ; table de charact�res : chiffres
   SACL  unite   ; ecrit char : unit�
    SETC    SXM             ; remet le sign extension
   .endm


with

   .bss Var,1
   .bss signe,1
   .bss millier,1
   .bss centaine,1
   .bss dizaine,1
   .bss unite,1
   .bss M8389,1
   .bss M5243,1
   .bss M52429,1
   .bss M5000,1

and initialisation

   LDP #M8389
   SPLK #8389, M8389
   SPLK #5243, M5243
   SPLK #52429, M52429
   SPLK #5000, M5000



Reply by Lotfi May 28, 20042004-05-28
"Raymond Toy" <toy@rtp.ericsson.se> a &#4294967295;crit dans le message news:
sxdpt8qc6e2.fsf@edgedsp4.rtp.ericsson.se...
> >>>>> "Jerry" == Jerry Avins <jya@ieee.org> writes: > > Jerry> Lotfi wrote: > > Jerry> ... > > >> f(M,s)= M/2^s/2^16 - 1/d > > Jerry> M/2^s/2^16 = (M/2^s)/2^16 = M/2^(s+16). Is that what you mean? > > I think so. But in the book, the computation is done like m*n/2^W/2^s > because on many processors the product is returned in 2 registers, so > m*n/2^W is just the register containing the most significant W bits of > the result. > > For a DSP that has a single register containing the product, your > result would work very nicely. > > Ray
of course, I have 2 words for product results my routine is : but there is a mistake somewhere, coz I don't see the correct result :-( I am in the debugging process :-) ; Convertit un "Word" hexa en "4 chars D&#4294967295;cimaux + signe" ConvDec .macro Var LACC Var BCND positif?, GEQ ZAC SUB Var SACL Var LACC #02Bh B evitneg? positif? LACC #02Dh evitneg? SACL *+ ; SPM 0 ;PM=00, no shift after multiplication ; Magic=8389; s=7; // d=1000 ; m=floor((Magic*ns>>W)>>s); LT M8389 MPY Var SPH tmp LACC tmp,9 ;16-7=9 SACH tmp ;ie 7 LSR ; ici on aurait du checker le d&#4294967295;passement de m>9! ; ns-=1000*m; LACC Var LT tmp MPY #1000 SPAC ;Subtract PREG from ACC SACL Var LACC tmp ADD #030h ; table de charact&#4294967295;res : chiffres SACL *+ ; ecrit char : millier ; Magic=5243; s=3; // d=100 ; c=floor((Magic*ns>>W)>>s); LT M5243 MPY Var SPH tmp LACC tmp,13 ;16-3=13 SACH tmp ;ie 3 LSR ; ns-=100*c; LACC Var LT tmp MPY #100 SPAC ;Subtract PREG from ACC SACL Var LACC tmp ADD #030h ; table de charact&#4294967295;res : chiffres SACL *+ ; ecrit char : centaine ; Magic=52429; s=3; // d=10 ; d=floor((Magic*ns>>W)>>s); LT M52429 MPY Var SPH tmp LACC tmp,13 ;16-3=13 SACH tmp ;ie 3 LSR ; ns-=10*m = u LACC Var LT tmp MPY #10 SPAC ;Subtract PREG from ACC SACL Var LACC tmp ADD #030h ; table de charact&#4294967295;res : chiffres SACL *+ ; ecrit char : dizaine LACC Var ADD #030h ; table de charact&#4294967295;res : chiffres SACL *+ ; ecrit char : unit&#4294967295; .endm
Reply by Raymond Toy May 27, 20042004-05-27
>>>>> "Jerry" == Jerry Avins <jya@ieee.org> writes:
Jerry> Lotfi wrote: Jerry> ... >> f(M,s)= M/2^s/2^16 - 1/d Jerry> M/2^s/2^16 = (M/2^s)/2^16 = M/2^(s+16). Is that what you mean? I think so. But in the book, the computation is done like m*n/2^W/2^s because on many processors the product is returned in 2 registers, so m*n/2^W is just the register containing the most significant W bits of the result. For a DSP that has a single register containing the product, your result would work very nicely. Ray
Reply by Raymond Toy May 27, 20042004-05-27
>>>>> "Lotfi" == nospam <Lotfi> writes:
Lotfi> the best routine :-)) to extract the numbers Lotfi> int m,c,d,u; Lotfi> int Magic, s; Lotfi> double Val; Lotfi> // floor 16 bits Lotfi> unsigned short ns=Val; // here the entry point Lotfi> int W=16; Lotfi> m=0; c=0; d=0; u=0; Lotfi> if (ns>32767) {printf("Attention n&#4294967295;gatif "); Lotfi> ns=-ns; } Lotfi> Magic=8389; s=7; // d=1000 Lotfi> m=floor((Magic*ns>>W)>>s); Lotfi> // if (m>10) alors d&#4294967295;passement affichage Lotfi> ns-=1000*m; Lotfi> Magic=5243; s=3; // d=100 Lotfi> c=floor((Magic*ns>>W)>>s); Lotfi> ns-=100*c; Lotfi> Magic=52429; s=3; // d=10 Lotfi> d=floor((Magic*ns>>W)>>s); Lotfi> u=ns-10*d; I believe these magic numbers might be wrong, since the assumption was that all the numbers would fit in a signed 16-bit integer. 52429 clearly doesn't fit. I think they should be d m s 1000 -31981 9 100 5243 3 10 26215 2 A negative m means that instead of computing m*n/2^W, we compute m*n/2^W + n. Ray
Reply by Lotfi May 26, 20042004-05-26
"Jerry Avins" <jya@ieee.org> a &#4294967295;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
Reply by Lotfi 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&#4294967295;gatif ");
                    ns=-ns; }
    Magic=8389; s=7;            // d=1000
    m=floor((Magic*ns>>W)>>s);
//    if (m>10)  alors d&#4294967295;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 Jerry Avins May 26, 20042004-05-26
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? ... Jerry -- Engineering is the art of making what you want from things you can get. &#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;
Reply by Lotfi 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 Lotfi 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 &#4294967295;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 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 Raymond Toy 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