Stampare Numeri Interi e Reali in Fortran

Questa lezione introduce i principali metodi per formattare e stampare numeri interi e reali in Fortran.

Verranno illustrati vari descrittori di formato, insieme a esempi pratici che mostrano come gestirne correttamente la larghezza di campo e l'allineamento.

Descrittori di Formato

Esistono molti tipi diversi di descrittori di formato in Fortran. Essi rientrano in quattro categorie di base:

    1. Descrittori di formato che descrivono la posizione verticale di una riga di testo.
    1. Descrittori di formato che descrivono la posizione orizzontale dei dati in una riga.
    1. Descrittori di formato che descrivono il formato di output di un determinato valore.
    1. Descrittori di formato che controllano la ripetizione di porzioni di un formato.

Tratteremo alcuni esempi comuni di descrittori di formato in questa lezione. In particolare, ci concentreremo sui descrittori adoperati per stampare numeri, sia interi che reali.

Altri descrittori di formato meno comuni saranno rimandati alle prossime lezioni.

La Tabella che segue contiene un elenco dei simboli usati con i descrittori di formato, insieme ai loro significati:

Simbolo Significato
c Numero di colonna
d Numero di cifre a destra del punto decimale per input o output reale
m Numero minimo di cifre da visualizzare
n Numero di spazi da saltare
r Conteggio di ripetizioni—quante volte usare un descrittore o gruppo di descrittori
w Larghezza del campo—numero di caratteri da usare per input o output
Tabella 1: Simboli usati con i descrittori di formato.

Stampare Numeri Interi: il Descrittore I

Il descrittore utilizzato per descrivere il formato di visualizzazione dei numeri interi è il descrittore I. Ha la forma generale

rIw

oppure

rIw.m

dove r, w e m hanno i significati riportati nella tabella di sopra.

I valori interi sono allineati a destra nei loro campi. Questo significa che gli interi sono stampati in modo che l'ultima cifra occupi la colonna più a destra del campo.

Se un intero è troppo grande per entrare nel campo in cui deve essere stampato, il campo viene riempito con asterischi. Ad esempio, le seguenti istruzioni:

integer :: i1 = -12
integer :: i2 = 4
integer :: i3 = -12345

write (*,200) i1, i1 + 12, i2, i3
write (*,210) i1, i1 + 12, i2, i3
write (*,220) i1, i1 + 12, i2, i3

200 format (' ', 2I5, I6, I10)
210 format (' ', 2I5.0, I6, I10.8)
220 format (' ', 2I5.3, I6, I5)

produrranno il seguente output:

   -12    0     4    -12345
   -12          4 -00012345
  -012  000     4*****

Osserviamo alcune cose:

  • Nella riga 200:
    • Lo specificatore 2I5 nel descrittore di formato 200 dice al compilatore di stampare due interi, ciascuno in un campo di cinque caratteri. Il primo intero è stampato come -12, il secondo come 0.
    • Lo specificatore I6 nel descrittore di formato 200 dice al compilatore di stampare un intero in un campo di sei caratteri. L'intero è stampato come 4.
    • Lo specificatore I10 nel descrittore di formato 200 dice al compilatore di stampare un intero in un campo di dieci caratteri. L'intero è stampato come -12345.
  • Nella riga 210:
    • Lo specificatore 2I5.0 nel descrittore di formato 210 dice al compilatore di stampare due interi, ciascuno in un campo di cinque caratteri. Inoltre specifica che il numero minimo di cifre da visualizzare è zero. Il primo intero è stampato come -12, il secondo, invece, non viene stampato.
    • Lo specificatore I6 nel descrittore di formato 210 funziona come sopra.
    • Lo specificatore I10.8 nel descrittore di formato 210 dice al compilatore di stampare un intero in un campo di dieci caratteri, con un minimo di otto cifre da visualizzare. L'intero è stampato come -00012345.
  • Nella riga 220:
    • Lo specificatore 2I5.3 nel descrittore di formato 220 dice al compilatore di stampare due interi, ciascuno in un campo di cinque caratteri. Inoltre specifica che il numero minimo di cifre da visualizzare è tre. Il primo intero è stampato come -012, il secondo come 000.
    • Lo specificatore I6 nel descrittore di formato 220 funziona come sopra.
    • Lo specificatore I5 nel descrittore di formato 220 dice al compilatore di stampare un intero in un campo di cinque caratteri. Tuttavia, poiché servono 6 caratteri per stampare -12345, il campo viene riempito con asterischi in quanto non c'è spazio sufficiente.

Il caso speciale del descrittore I0, di lunghezza zero, fa sì che l'intero venga scritto con una larghezza di campo variabile sufficiente a contenere tutte le cifre dell'intero. Ad esempio, le seguenti istruzioni:

integer :: i1 = -12
integer :: i2 = 4
integer :: i3 = -12345

write (*,100) i1, i2, i3

100 format (I0,1X,I0,1X,I0)

produrranno il seguente output:

-12 4 -12345

Questa forma del descrittore di formato è particolarmente utile per garantire che i dati vengano sempre visualizzati, ma non è adatta per creare tabelle di dati, poiché le colonne non risulteranno correttamente allineate.

Stampare Numeri Reali: il Descrittore F

Uno dei descrittori di formato utilizzati per descrivere il formato di visualizzazione dei numeri reali è il descrittore F. Ha la forma:

rFw.d

dove r, w e d hanno i significati indicati nella Tabella di sopra.

I valori reali sono stampati allineati a destra nei loro campi. Se necessario, il numero viene arrotondato prima di essere visualizzato. Ad esempio, supponiamo che la variabile pi contenga il valore 3.141593.

Se questa variabile viene visualizzata utilizzando il descrittore di formato F7.3, il valore visualizzato sarà:

   3.141

D'altra parte, se il numero visualizzato include più cifre significative di quelle contenute nella rappresentazione interna del numero, verranno aggiunti zeri extra a destra del punto decimale. Se la variabile pi viene visualizzata con un descrittore di formato F10.8, il valore risultante sarà:

3.14159300

Se un numero reale è troppo grande per entrare nel campo in cui deve essere stampato, il campo viene riempito con asterischi.

Ad esempio, le seguenti istruzioni:

real :: a = -12.3
real :: b = .123
real :: c = 123.456

write (*,200) a, b, c
write (*,210) a, b, c

200 format (2F6.3, F8.3)
210 format (3F10.2)

produrranno l'output

****** 0.123 123.456
    -12.30      0.12    123.46

Osserviamo alcune cose:

  • Nella riga 200:
    • Lo specificatore 2F6.3 nel descrittore di formato 200 dice al compilatore di stampare due numeri reali, ciascuno in un campo di sei caratteri. Inoltre, specifica che il numero di cifre a destra del punto decimale è tre. Il primo numero reale è stampato come ******, in quanto non può essere stampato, il secondo come 0.123.
    • Lo specificatore F8.3 nel descrittore di formato 200 dice al compilatore di stampare un numero reale in un campo di otto caratteri, con tre cifre a destra del punto decimale. Il numero reale è stampato come 123.456.
  • Nella riga 210:
    • Lo specificatore 3F10.2 nel descrittore di formato 210 dice al compilatore di stampare tre numeri reali, ciascuno in un campo di dieci caratteri. Inoltre, specifica che il numero di cifre a destra del punto decimale è due. I numeri reali sono stampati come -12.30, 0.12 e 123.46.

Stampare Numeri Reali: il Descrittore E

I dati reali possono anche essere stampati in notazione esponenziale o notazione scientifica utilizzando il descrittore E.

La notazione scientifica è un metodo popolare utilizzato da scienziati e ingegneri per visualizzare numeri molto grandi o molto piccoli. Consiste nell'esprimere un numero come un valore normalizzato compreso tra 1 e 10, moltiplicato per 10 elevato a una potenza.

Per capire la comodità della notazione scientifica, consideriamo i seguenti due esempi dalla chimica e dalla fisica.

Il numero di Avogadro è il numero di atomi in una mole di una sostanza. Può essere scritto come:

602\,000\,000\,000\,000\,000\,000\,000

oppure espresso in notazione scientifica come:

6.02 \times 10^{23}

D'altra parte, la carica di un elettrone è:

0.\,000\,000\,000\,000\,000\,000\,160\,2 \quad \text{Coulomb}

Questo numero può essere espresso in notazione scientifica come:

1.602 \times 10^{-19}

La notazione scientifica è chiaramente un modo molto più comodo per scrivere questi numeri.

Il descrittore di formato E ha la forma

rEw.d

dove r, w e d hanno i significati indicati nella tabella di sopra.

A differenza della notazione scientifica standard, i valori reali visualizzati in notazione esponenziale con il descrittore E sono normalizzati in un intervallo compreso tra 0.1 e 1.0. Cioè, sono visualizzati come un numero tra 0.1 e 1.0 moltiplicato per una potenza di 10.

Ad esempio, la notazione scientifica standard per il numero 4096.0 sarebbe:

4.096 \times 10^3

mentre l'output del computer con il descrittore E sarebbe

0.4096 \times 10^4

Poiché non è facile rappresentare gli esponenti su una stampante a riga, l'output del computer apparirebbe sulla stampante come

0.4096E+04

Se un numero reale non può entrare nel campo in cui deve essere stampato, il campo viene riempito con asterischi.

È necessario prestare particolare attenzione alle dimensioni del campo quando si lavora con il descrittore di formato E, poiché molti elementi devono essere considerati per determinare la larghezza dell'output.

Ad esempio, supponiamo di voler stampare una variabile in formato E con quattro cifre significative di precisione. In tal caso, è necessaria una larghezza di campo di 11 caratteri, come mostrato di seguito:

  • 1 per il segno della mantissa;
  • 2 per lo zero e il punto decimale;
  • 4 per la mantissa effettiva;
  • 1 per la E;
  • 1 per il segno dell'esponente;
  • 2 per l'esponente stesso.

In totale sono 11 caratteri come mostrato di seguito

\pm \texttt{0.ddddE}\pm \texttt{ee}

In generale, la larghezza di un campo del descrittore di formato E deve soddisfare l'espressione:

w \ge d + 7

oppure il campo potrebbe essere riempito con asterischi.

Se il numero da visualizzare nel campo è positivo, allora la larghezza del campo w deve essere di almeno sei caratteri maggiore di d. Se il numero è negativo, è necessario un carattere extra per il segno meno. Quindi, in generale, w deve essere ≥ d + 7. Inoltre, si noti che alcuni compilatori sopprimono lo zero iniziale, quindi è richiesta una colonna in meno.

I sette caratteri extra richiesti sono usati come segue:

  • 1 per il segno della mantissa;
  • 2 per lo zero e il punto decimale;
  • 1 per la E;
  • 1 per il segno dell'esponente;
  • 2 per l'esponente stesso.

Ad esempio, le seguenti istruzioni:

real :: a = 1.2346E6
real :: b = 0.001
real :: c = -77.7E10
real :: d = -77.7E10

write (*,200) a, b, c, d
200 format (2E14.4, E13.6, E11.6)

produrranno l'output:

    0.1235E+07    0.1000E-02-0.777000E+12***********

In questo caso abbiamo:

  1. Il formato 2E14.4 che stampa due numeri reali con 14 caratteri e quattro cifre dopo il punto. Pertanto:

    • 1.2346E6 viene normalizzato in 0.12346E7 ma, poiché ha 5 cifre dopo il punto, viene arrotondato a 0.1235E+07
    • 0.001 viene normalizzato a 0.1E-2 ma, poiché ha solo una cifra dopo il punto vengono aggiunti degli zeri e diventa 0.1000E-02
  2. Il formato E13.6 stampa un numero con 13 caratteri di cui 6 cifre dopo il punto. Pertanto:

    • -77.7E10 viene normalizzato a -0.777E+12 e vengono aggiunti 3 zeri diventando: -0.777000E+12
  3. Infine, il formato E11.6 stampa un numero con 11 caratteri di cui 6 dopo il punto. Pertanto:

    • -77.7E10 viene normalizzato a -0.777E+12 e vengono aggiunti 3 zeri diventando: -0.777000E+12. Tuttavia, il risultato è di 13 caratteri, non 11, per cui non può essere stampato e al suo posto vengono stampati degli asterischi. Risulta violata, infatti, la condizione vista sopra:
    11 \ngeq 6 + 7

La presenza dello zero iniziale in un descrittore di formato E è opzionale, e la sua presenza o meno può variare a seconda del compilatore.

Alcuni compilatori visualizzano lo zero iniziale, mentre altri no. Le due righe seguenti mostrano l'output che potrebbe essere prodotto da due compilatori diversi per questo esempio, e entrambi sarebbero considerati corretti.

    0.1235E+07    0.1000E-02-0.777000E+12***********
     .1235E+07     .1000E-02 -.777000E+12***********

Stampare Numeri Reali: il Descrittore ES

Come abbiamo detto sopra, l'output del descrittore di formato E non stampa i numeri reali esattamente in notazione scientifica, anche perché normalizza la mantissa ad un valore compreso tra 0.1 e 1.0.

La notazione scientifica adoperata in letteratura nei testi scientifici ed ingegneristici, invece, normalizza la mantissa tra 1.0 e 10.0. Per questo motivo, il compilatore Fortran fornisce un altro descrittore di formato, ES, che produce un output in notazione scientifica standard.

Questo descrittore stampa i numeri reali in notazione scientifica standard, con la mantissa normalizzata tra 1.0 e 10.0.

La sua forma generale è:

rESw.d
dove r, w e d hanno i significati indicati nella Tabella di sopra.

La formula per calcolare la larghezza del campo è la stessa del descrittore E:

w \ge d + 7

anche se il descrittore ES può mostrare una cifra significativa in più, dal momento che sostituisce lo 0 prima del punto decimale con una cifra significativa.

Vediamo un esempio:

real :: a = 1.2346E6
real :: b = 0.001
real :: c = -77.7E10

write (*, 200) a, b, c
200 format (2ES14.4, ES12.6)

Questo esempio produrrà il seguente output:

    1.2346E+06    1.0000E-03************

Il terzo numero, contenuto nella variabile c, verrà stampato con tutti asterischi dal momento che il descrittore ES12.6 non soddisfa l'equazione vista sopra.

In realtà, se il numero da visualizzare è positivo, l'equazione da soddisfare per visualizzarlo è:

w \ge d + 6

in quanto non è necessario il carattere per il segno della mantissa. Se il numero è negativo, è necessario un carattere extra per il segno meno. Quindi, in generale, w deve essere ≥ d + 7.

Consiglio

Preferire il descrittore ES al descrittore E

Quando bisogna visualizzare numeri molto grandi o molto piccoli è sempre meglio preferire la notazione scientifica standard, quindi il descrittore ES è da preferire al descrittore E.

Questo per rendere più chiaro il significato dei numeri visualizzati, e per evitare confusione tra i lettori.

In Sintesi

In questa lezione abbiamo visto come sfruttare le istruzioni write e format per rappresentare in output numeri interi e numeri reali in virgola mobile.

In particolare abbiamo visto:

  • Come stampare numeri interi utilizzando il descrittore I;
  • Come stampare numeri reali utilizzando i descrittori F, E e ES;
  • Come calcolare la larghezza del campo per i descrittori E e ES;
  • Come stampare numeri reali in notazione scientifica standard;
  • Come stampare numeri reali in notazione esponenziale.

Nella prossima lezione, invece, vedremo come stampare altri tipi di dato: tipi booleani o logici e stringhe.