Vai al contenuto

Problemi con elevazione a potenza

Home Forum Informazioni ambiente di sviluppo LogicLab Problemi con elevazione a potenza

Stai visualizzando 2 post - dal 1 a 2 (di 2 totali)
  • Autore
    Post
  • #46691
    Marcello
    Partecipante

    Stò realizzando un codice su numero UDINT a base 7 per compattare una matrice ad USINT.  La sintassi per la sua generazione è:

    FOR t:=0 TO 10 DO
    Valore:=Valore+Data[t]*TO_UDINT(POW(7.0,TO_REAL(t)));
    END_FOR;

    dove Data è la matrice contente valori 0 a 6. Il problema è che quando t è uguale a 9 e a 10 il calcolo della potenza è errato e pertanto il codice generato è sbagliato.

    Ho verificato che POW(7.0,9.0) da come risultato 40353608 anzichè 40353607 e POW(7.0,10.0) restituisce  282475264 anziché 282475249

    Lo SlimLine è un PCB135A110 il SW è SFW184B070. Ho provato con il simulatore e le cose cambiano di poco: 7^9 = 40353604;  7^10=282475232. Cosa posso fare?

    #46695
    Sergio Bertana
    Amministratore del forum

    Il problema è nella risoluzione dei numeri a virgola mobile, il formato REAL utilizzato sia dal sistema reale che dal simulatore è IEEE 754 su 32 bits. Questo formato su numeri molto piccoli e molto grandi ha imprecisioni fisiologiche che percentualmente sul valore del numero incidono pochissimo. Nel caso (7^10) hai un errore di 15 su oltre 282 milioni.

    Come risolvere… la prima idea che mi viene se utilizzi sempre numeri interi è lavorare con UDINT e non con REAL ecco il listato di una funzione RToPower che eleva a potenza (Screenshot e download progetto).

    FUNCTION RToPower: UDINT
    VAR
    i : UDINT; (* Auxiliary variable *)
    END_VAR
    
    VAR_INPUT
    Base : UDINT; (* Base value *)
    Exponent : UDINT; (* Esponent value *)
    END_VAR
    
    IF (Exponent = 0) THEN RToPower:=0; RETURN; END_IF;
    RToPower:=Base; //Result
    IF (Exponent = 1) THEN RETURN; END_IF;
    
    FOR i:=0 TO (Exponent-2) DO
    RToPower:=RToPower*Base;
    END_FOR;
Stai visualizzando 2 post - dal 1 a 2 (di 2 totali)
  • Devi essere connesso per rispondere a questo topic.