Flyttalslib till 16F887 ?

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
pi314
Inlägg: 6944
Blev medlem: 23 oktober 2021, 19:22:37
Ort: Stockholm

Re: Flyttalslib till 16F887 ?

Inlägg av pi314 »

Kod: Markera allt

if (x>0.5) r = sqrt(2.0)*r(x-0.5);
Användarvisningsbild
rvl
Inlägg: 6478
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: Flyttalslib till 16F887 ?

Inlägg av rvl »

Provkört och ser ut att ge rätt svar:

Kod: Markera allt

#include <stdio.h>
#include <stdlib.h>

int main(){
  int i;
  double x, p, q, r, xx;

  double M_EXP_P[] ={
            1513.906799054338915944,
            20.202065651286927227,
            0.023093347753750234,
          };

  double M_EXP_Q[] ={
            4368.211662727558498354,
            233.184211427481623793,
            1.000000000000000000,
          };

  x=0.32;  //försöker få fram 2**0.32 som testvärde

//        jsr _TABLE_LD          *03FB   2013               M         CALL    _TABLE_LD
//                               *                      00072         FP_ADD                  ; P += Constant
//        jsr _FP_ADD            *03FC   2292               M         CALL    _FP_ADD
//                               *                      00073         TRarg_LOAD      FParg1          ; P *= FParg1
//        lod a,#FParg1          *03FD   3044               M         movlw   FParg1
//        jsr _TRarg_LOAD        *03FE   21E3               M         CALL    _TRarg_LOAD
//                               *                      00074         FP_MUL
//        jsr _FP_MUL            *03FF   22CB               M         CALL    _FP_MUL

  p=q=0.0;
  xx = x*x;
  for (i=0; i<3; i++){
    p+=M_EXP_P[i]*xx;
    q+=M_EXP_Q[i]*xx;
    xx*=x*x;
  };
  p*=x;

  r=(q+p)/(q-p);

  printf("%5.17f,    1.2483305489016119 236077142958776594933782317... \n", r);
//              ---> 1.2483305489016119|0
  return(0);
};//main
Användarvisningsbild
pi314
Inlägg: 6944
Blev medlem: 23 oktober 2021, 19:22:37
Ort: Stockholm

Re: Flyttalslib till 16F887 ?

Inlägg av pi314 »

Tankar om numerisk beräkning av polynom
Ett enkelt andragradspolynom kan skrivas så här

p(x) = p0 + p1*x + p2*x**2

När värdet av polynomet ska beräknas numeriskt kan man göra det på två sätt.

Som det skrivits ovan.
p(x) = p0 + p1*x + p2*x**2

Eller så här.
p(x) = (p2*x + p1)*x + p0

Om man har bråttom så är det andra sättet snabbare.
Hur avrundningsfel utbreder sig genom beräkningen och påverkar slutresultatet kan bero på koefficienternas värden och värdet på x.



Edit:
Se Horners metod.
After the introduction of computers, this algorithm became fundamental for computing efficiently with polynomials.
https://en.wikipedia.org/wiki/Horner%27s_method
Användarvisningsbild
rvl
Inlägg: 6478
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: Flyttalslib till 16F887 ?

Inlägg av rvl »

Bild
Marta skrev: 9 januari 2025, 15:37:58 Lyckades komplettera de trasiga tabellerna med de snuttar av sidor Google visar från en ebook.
Grattis för detta, det är inte mycket G är villig att visa och i bland visas nån helt annan del från sidan med sökresultatet.
content.png
Ser man inte resultat och man saknar bara en siffra så kan man brute force söka på den och se OM man får resultat, då vet man ju utan att behöva se resultatet.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
rvl
Inlägg: 6478
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: Flyttalslib till 16F887 ?

Inlägg av rvl »

pi314 skrev: 10 januari 2025, 11:45:52 Eller så här.
p(x) = (p2*x + p1)*x + p0
Naturligtvis... Var nog inte helt "vaken" när jag såg på det här i går, dessutom provkörde jag din kod med hjälp av den verktygskedja jag hade närmast och resultatet blev blankt NOLL, för long double stöddes dåligt och inte alls i printf. :doh:
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7283
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Flyttalslib till 16F887 ?

Inlägg av Marta »

long double i gcc kräver ett %#.#Lf i printf, annars blir det bara nollor.

Tack för all hjälp. Här är det färdiga resultatet. Har testat några värden i emulator. Ännu inte testat hur många siffror det håller för.

Finns lite klumpigheter, macrofantasten som gjort originalet har åstadkommit en del "compiler madness" på sina ställen i hela den kompletta koden.

Har Ni något förslag till bättre hantering när ingångsvärdet är 0.5<x<1 tas det tacksamt emot.

Kod: Markera allt

                               *                      00647 ;===============================================================
                               *                      00648 ;       EXP(X)
                               *                      00649 ;       T1043 pg170
                               *                      00650 ;
                               *                      00651 ;       exp(X) = P(X) , 2 ** X/LN(2) == E ** X
                               *                      00652 ;===============================================================
                               *                      00708
                               *                      00709 ;===============================================================
                               *                      00710
                               *                      00711
_FP_EXP                                                    *_FP_EXP ; FPac = EXP(FPac)
                                                           *        TRarg_TABLE_LD   M_LN2 ; TRarg = Ln(2)
                                                           *        TABLE_SET_SOURCE        M_LN2
                                                           *        LOAD16I table_ptr,M_LN2
                                                           *        IN_LOADI table_ptr,M_LN2,2
                                                           *        local index = 0
                                                           *        WHILE index < 2
                                                           *        LOAD8I table_ptr+index, ((M_LN2) >> (index*8)) & 0xff
        *lod a,#<M_LN2/2                                   *         movlw LOW(((M_LN2) >> (index*8)) & 0xff)
        *lod table.ptr,a                                   *         movwf table_ptr+index
                                                           *index   = index + 1
                                                           *        LOAD8I table_ptr+index, ((M_LN2) >> (index*8)) & 0xff
        *lod a,#>M_LN2/2                                   *         movlw LOW(((M_LN2) >> (index*8)) & 0xff)
        *lod table.ptr+1,a                                 *         movwf table_ptr+index
                                                           *index   = index + 1
        lod a,#M_LN2            et log(2)..                *        ENDW
        jsr _TRarg_TABLE_LDx                               *        CALL _TRarg_TABLE_LD
                                                           *        FP_DIV
        jsr _FP_DIV             ..to make 2**x into e**x   *        CALL    _FP_DIV
                                                           *
                                                           *        CLR8    FPquad;
        stz FPquad              assume no end processing   *        clrf    FPquad
                                                           *        JMP_BCLR        FPac_SIGN,7,_fp_exp1
                                                           *        SKIP_BSET FPac_SIGN,7
        sbs FPac_SIGN,7         negative?                  *        btfss FPac_SIGN,7
                                                           *        JMP     _fp_exp1
        jmp _fp_exp1                                       *        goto    _fp_exp1
                                                           *        CLR8    FPac_SIGN
        stz FPac_SIGN           yes, clear sign            *        clrf    FPac_SIGN
                                                           *        LOAD8I  FPquad,1
        lod a,#1                invert at end              *        movlw LOW(1)
        lod FPquad,a                                       *        movwf FPquad
_fp_exp1                                                   *_fp_exp1
                                                           *
                                                           *        FP_SPLIT        ; FPac = integer(real) , FParg = fraction(xp)
        jsr _FP_SPLIT           separate wholes/fraction   *        CALL    _FP_SPLIT
                                                           *        FP_U32          ; AC32 = integer(fixed)
        jsr _FP_U56             wholes to integer..        *        CALL    _FP_U32
                                                           *        MOV8    FPflag,AC32_LSB
        lod a,AC56_LSB          ..and ave it               *        movfw AC32_LSB
        lod FPflag,a                                       *        movwf FPflag

        jsr _FPac_SWAP          fraction to ac             *
                                                           *        TRarg_STORE     FParg1
        lod a,#0x7d             test exp for <0.5          *
        sur a,FPac                                         *
        sfc cy                                             *
        jmp .low                was <0.5, do noting        *
        smb FPquad,1            flag compensation needed   *
        lod a,#M_HALF           -0.5 to make it <0.5       *
        jsr _TRarg_TABLE_LDx                               *
        jsr _FP_SUB                                        *
.low                                                       *
                                                           *
        lod a,#fparg2           keep x                     *
        jsr _trac_store                                    *
                                                           *
        lod a,#FParg            x**2                       *
        jsr _TRac_STORE                                    *
        jsr _fp_mul                                        *
        lod a,#FParg1           setup for poly             *
        jsr _TRac_STORE                                    *
                                                           *
        lod a,#M_EXP_P          do poly for p              *
        jsr _TABLE_SETx_TRarg                              *
        jsr _fpac_clr                                      *
        jsr _POLY_FParg1x                                  *
        jsr _POLY_FParg1x                                  *
        jsr _TABLE_LDx                                     *
        jsr _FP_ADD                                        *
                                                           *
        lod a,#fparg2           *x                         *
        jsr _trarg_load                                    *
        jsr _fp_mul                                        *
                                                           *
        lod a,#fparg2           keep result                *
        jsr _trac_store                                    *
                                                           *
        lod a,#M_EXP_Q          do poly for q              *
        jsr _TABLE_SETx_TRarg                              *
        jsr _fpac_clr                                      *
        jsr _POLY_FParg1x                                  *
        jsr _POLY_FParg1x                                  *
        jsr _TABLE_LDx                                     *
        jsr _FP_ADD                                        *
                                                           *
        lod a,#fparg2           q - x*p                    *
        jsr _trarg_load                                    *
        jsr _fp_sub                                        *
                                                           *
        lod a,#fparg1           keep it                    *
        jsr _trac_store                                    *
                                                           *
        jsr _fp_add             q + x*p                    *
        jsr _fp_add                                        *
                                                           *
        lod a,#fparg1           do final div               *
        jsr _trarg_load                                    *
        jsr _fp_div                                        *
                                                           *
        sbs FPquad,1            need -0.5 compensation?    *
        jmp .nohigh             no                         *
        lod a,#M_SQRT2          yes, * sqrt(2)             *
        jsr _trarg_table_ldx                               *
        jsr _fp_mul                                        *
.nohigh                                                    *
                                                           *
                                                           *
        lod a,FPflag            get whole part             *        movfw   FPflag
                                                           *        FP_LDEXP
        jsr _FP_LDEXP           it's 2**x, so just make it exp     CALL    _FP_LDEXP
                                                           *
                                                           *        JMP_BCLR        FPquad,0,_fp_expx
                                                           *        SKIP_BSET FPquad,0
        sbs FPquad,0            was it negative?           *        btfss FPquad,0
                                                           *        JMP     _fp_expx
        jmp _fp_expx            no, done                   *        goto    _fp_expx
                                                           *        FParg_ONE                       ; if(sign) r = 1.0 / r
        jsr _FParg_ONE          yes, invert it             *        CALL    _FParg_ONE
                                                           *        FPac_SWAP
        jsr _FPac_SWAP                                     *        CALL    _FPac_SWAP
                                                           *        FP_DIV
        jsr _FP_DIV                                        *        CALL    _FP_DIV
_fp_expx                                                   *_fp_expx
                                                           *        ENDSUB
        rts                     done                       *        return


guckrum
Inlägg: 1840
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Flyttalslib till 16F887 ?

Inlägg av guckrum »

Är tanken att du skall använda denna för att dra rötter ur flyttal?

Så du behöver transmografera input och output så att det passar i befintligt mantissa/exponent-format, typ vänsterskiftat förbi första ettan?
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7283
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Flyttalslib till 16F887 ?

Inlägg av Marta »

Är inte med på riktigt vad Du avser där. Jag är en obildad klåpare som bara kan det jag behövt kunna.

Det är tänkt som allmänt flyttalslib. log/exp är ju nödvändigt för mycket. Beräkning av dB, eller kubikrot t.ex. Det finns en färdif pow x**y som beror av log samt den här exp.

Originalet är lite abandonware och bara har 32-bit mantissa. Nu är den ökad till 56-bit inklusive ettan. Adresseringen av variabler är ändrad så de måste ligga på adress jämnt delbar med 8, då täcks 2K med 1 byte. Det är även de-macrofierat, något som nog ogillas av upphovsmannen.

Här är länk till originalet hos Microsoft:
https://github.com/magore/picfloat
Skriv svar