Vai al contenuto

Definizione valore NaN su variabili REAL

Home Forum Programmazione IEC 61131 (LogicLab) Definizione valore NaN su variabili REAL

Stai visualizzando 5 post - dal 1 a 5 (di 5 totali)
  • Autore
    Post
  • #58872
    Rubox
    Partecipante

    Mi conferma che l’unico modo per assegnare ad una variabile REAL il classico valore di NaN è quello di assegnargli SQRT(-1)? La divisione per zero non me la lascia fare.

    Oppure in qualche libreria è definito tale valore?

    #58874
    Sergio Bertana
    Amministratore del forum

    La definizione NaN è un acronimo che indica “Not A Number”. I valore NAN per una variabile REAL in formato IEE754 è un valore che ha tutti gli 8 bit di esponente a “1” e la mantissa diversa da “0”, il segno non importa.

    Quindi se lo rappresentiamo in esadecimale sarà un numero del tipo 16#7F8FFFFF, ma qualsiasi altro numero che mantenga tutti gli 8 bit di esponente a “1” e la mantissa diversa da “0” verrà indicato cone un NaN. Risulta quindi evidente che non c’è un numero univoco per rappresentare il NaN, se vuoi settare una variabile a NaN puoi utilizzare una definizione del tipo:

    VAR
        APtr : @DWORD;
        RVars : ARRAY[0..3] OF REAL;
    END_VAR
    
        // Definizione valori REAL in esadecimale. Vedi sito:
        // https://www.binaryconvert.com/convert_float.html
    
        APtr:=ADR(RVars[0]);
        @APtr:=16#41280000; //10.5
    
        APtr:=ADR(RVars[1]);
        @APtr:=16#42C80000; //100.0
    
        APtr:=ADR(RVars[2]);
        @APtr:=16#7F8FFFFF; //NaN (Not a number)
    
        APtr:=ADR(RVars[3]);
        @APtr:=16#7F800001; //NaN (Not a number)

    Come vedi dall’esempio sia il valore 16#7F8FFFFF che 16#7F800001 sono riconosciuti come NaN. Da quanto espresso si deduce che non è possibile fare comparazioni sul valore NaN, e certamente potrebbero servire due cose:

    • Una definizione di NaN per settare il valore in una variabile.
    • Una funzione di verifica se un numero REAL e NAN. La funzione deve verificare se il numero ha gli 8 bit di esponente a “1” e la mantissa diversa da “0”.
    #58889
    Rubox
    Partecipante

    Grazie per la spiegazione.
    Quindi assegnando direttamente il valore esadecimale 16#7F8FFFFF non ottengo il risultato voluto, ma devo assegnarlo tramite un puntatore alla variabile stessa?

    #58891
    Sergio Bertana
    Amministratore del forum

    Si passa per un puntatore per “fregare” il compilatore, se assegnassi il valore 16#7F8FFFFF (Decimale 2.140.143.615) ad una variabile REAL essa assumerebbe il valore 16#4EFF2000 (Come puoi verificare con un convertitore come questo).

    Per poter impostare un valore esadecimale devo avere una variabile di tipo DWORD, nel linguaggio ST non c’è il costrutto UNION che permette di unire variabili di tipo diverso, quindi l’unico escamotage che ho trovato è utilizzare un puntatore.

    Ma magari nel forum c’è qualcuno che ha una idea migliore.

    #58892
    Rubox
    Partecipante

    Seguendo la Sua idea, e cercando meglio nel forum, ho creato la funzione di verifica per valore NaN e Infinito.

    Se ho ben capito: su PLC se definisco una variabile REAL e le assegno un valore esadecimale, questo valore è convertito nel formato standard a 32 bit. Per scrivere direttamente i 32 bit devo farlo tramite puntatore che accede direttamente alla memoria dell variabile e non passa attraverso la codifica.

    Il link alla discussione da cui ho attinto per la funzione di verifica Nan e Infinito è questo

Stai visualizzando 5 post - dal 1 a 5 (di 5 totali)
  • Devi essere connesso per rispondere a questo topic.