Confrontare il valore assoluto di un numero reale

  • Creatore
    Topic
  • #99675
    Liverpool
    Partecipante
      Up
      0
      Down
      ::


      Ho un numero reale conservato in una marco (per esempio -1.5). Vorrei realizzare un condizionale che esegue una parte di codice se il suo valore assoluto è 1.5. Non avendo a disposizione la funzione modulo, ho pensato di moltiplicare la macro per sé stessa e confrontarla con 2.25. Avevo pensato a qualcosa del genere:
      `\ifdim\numexpr\x*\x\relax pt=2.25 pt`
      ma ovviamente non funziona per via del segno negativo.
      Domanda secca: come faccio a confrontare il valore assoluto di un numero reale con un altro?

      Grazie

    Visualizzazione 2 filoni di risposte
    • Autore
      Risposte
      • #99676
        OldClaudio
        Partecipante
          Up
          0
          Down
          ::


          Non devi usare aritmetica numerica, ma aritmetica delle dimensioni; se \x è un registro numerico non può contenere un numero reale; se è una dimensione lo puoi fare ma mantenendo le dimensioni giuste; nel seguito parto dal presupposto che \x sia una dimensione cioè sia stato dichiarato alla TeX con \newdimen o alla LaTeX con \newlength; allora`\ifdim\dimexpr\x*\x/\p@ >2.25pt …\else ….\fi`
          La macro \p@ contiene la lunghezza di 1pt; siccome contiene il segno @ devi usare \makeatletter oppure devi definire una lunghezza \unpunto che contenga il valore di 1pt e usare \unpunto al posto di ]p@.

          La speigazione di quello che ho scritto si trova nella documentazione di etex, nell’Hanbook commentato e nella Guid GuIT.

          In breve l’espressione prima della disuguaglianza è un valore in punti (il segno negativo del contento di \x è irrilevante), ma il primo prodotto rappresenta un quadrato di lunghezza espressa in punti quadrati, ma dividendolo per 1pt torna ea dessere una semplice lunghezza in punti che può essere confrontata con 2.25pt. Senza dividere per 1pt vorresti confrontare una superficie con una lunghezza 😈

          La cosa è ancora più chiara se pensi a come lavora TeX con numeri interi; le lunghezze internamente soni rappresentate con gli scaled point, che sono la frazione 2^{-16} di un punto tipografico; ogni lunghezza ha un valore assoluto rappresentato al massimo da 30 bit, gli ultimi 16 dei quali, quindi, rappresentano la frazione binaria dopo il separatore decimale; quando moltiplichi due lunghezze vai in overflow facilmente, perché al massimo ti viene un risultato di 60 o 61 bit, ma quasi sempre di più di 32 bit, che non sta in una parola di 32 bit; dunque etex mette il prodotto in una longword intera di 64 bit, di cui i 32 bit meno significativi rappresentano la parte fratta; dividendo per la lunghezza di 1p toglie gli ultimi 16 bit meno significativi, quindi se le due lunghezze iniziali non sono troppo grandi, il risultato finale può stare in una parola di 32 bit; non è escluso l’overflow, ma è meno facile che con l’aritmetica su 32 bit. L’algoritmo di etex provvede agli appositi messaggi in caso di overflow, e provvede all’arrotondamento del risultato invece di produrre il suo troncamento come farebbe l’aritmetica intera di tex.

          Io non lo uso mai, ma mi pare che il pacchetto calc abbia qualche suo comando che provvede al calcolo del vaoroe assoluto; controlla, ma anche calc usa le espressioni dimensionali di etex.

        • #99677
          Liverpool
          Partecipante
            Up
            0
            Down
            ::


            Grazie. Ho letto a suo tempo sia la guida GuIT (per prima), sia il manuale di etex. Il problema è nato dal fatto che il numero da confrontare è memorizzato in una macro di pgf e per questo volevo usare [tt]\numexpr[/tt] al posto di [tt]\dimexpr[/tt] seppure con [tt]\ifdim[/tt] per il confronto tra numeri reali. Vorrà dire che valuterò se sia più conveniente caricare il numero in una dimensione oppure utilizzare due [tt]\ifdim[/tt] annidati per i due valori opposti.

            Ciao

          • #99678
            OldClaudio
            Partecipante
              Up
              0
              Down
              ::


              Allora puoi evitare tutto ciò con una macro`\newcommand\valass[1]{\ifdim#1<0pt -#1\else#1\fi}`e poi fare semplicemente
              ` \expadafter\ifdim\valass{\x}>0pt … \else … \fi`Probabilmente [tt]expandafter[/tt] è superfluo, ma non guasta.

          Visualizzazione 2 filoni di risposte
          • Devi essere connesso per rispondere a questo topic.

          Go to top