Fortran - Numeri
I numeri in Fortran sono rappresentati da tre tipi di dati intrinseci:
- Tipo intero
- Tipo reale
- Tipo complesso
Tipo intero
I tipi interi possono contenere solo valori interi. L'esempio seguente estrae il valore più grande che potrebbe essere contenuto in un normale numero intero di quattro byte:
program testingInt
implicit none
integer :: largeval
print *, huge(largeval)
end program testingInt
Quando compili ed esegui il programma sopra, produce il seguente risultato:
2147483647
Si prega di notare che il file huge()funzione fornisce il numero più grande che può essere contenuto dal tipo di dati intero specifico. È inoltre possibile specificare il numero di byte utilizzando ilkindspecificatore. Il seguente esempio lo dimostra:
program testingInt
implicit none
!two byte integer
integer(kind = 2) :: shortval
!four byte integer
integer(kind = 4) :: longval
!eight byte integer
integer(kind = 8) :: verylongval
!sixteen byte integer
integer(kind = 16) :: veryverylongval
!default integer
integer :: defval
print *, huge(shortval)
print *, huge(longval)
print *, huge(verylongval)
print *, huge(veryverylongval)
print *, huge(defval)
end program testingInt
Quando compili ed esegui il programma sopra, produce il seguente risultato:
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647
Tipo reale
Memorizza i numeri in virgola mobile, come 2.0, 3.1415, -100.876, ecc.
Tradizionalmente ce n'erano due diversi real tipi: il tipo reale predefinito e double precision genere.
Tuttavia, Fortran 90/95 fornisce un maggiore controllo sulla precisione dei tipi di dati reali e interi tramite kind specificatore, che studieremo a breve.
L'esempio seguente mostra l'uso del tipo di dati reale:
program division
implicit none
! Define real variables
real :: p, q, realRes
! Define integer variables
integer :: i, j, intRes
! Assigning values
p = 2.0
q = 3.0
i = 2
j = 3
! floating point division
realRes = p/q
intRes = i/j
print *, realRes
print *, intRes
end program division
Quando compili ed esegui il programma sopra, produce il seguente risultato:
0.666666687
0
Tipo complesso
Viene utilizzato per memorizzare numeri complessi. Un numero complesso ha due parti: la parte reale e la parte immaginaria. Due unità di memorizzazione numeriche consecutive memorizzano queste due parti.
Ad esempio, il numero complesso (3.0, -5.0) è uguale a 3.0 - 5.0i
La funzione generica cmplx()crea un numero complesso. Produce un risultato le cui parti reali e immaginarie sono a precisione singola, indipendentemente dal tipo di argomenti di input.
program createComplex
implicit none
integer :: i = 10
real :: x = 5.17
print *, cmplx(i, x)
end program createComplex
Quando compili ed esegui il programma sopra, produce il seguente risultato:
(10.0000000, 5.17000008)
Il seguente programma dimostra l'aritmetica dei numeri complessi:
program ComplexArithmatic
implicit none
complex, parameter :: i = (0, 1) ! sqrt(-1)
complex :: x, y, z
x = (7, 8);
y = (5, -7)
write(*,*) i * x * y
z = x + y
print *, "z = x + y = ", z
z = x - y
print *, "z = x - y = ", z
z = x * y
print *, "z = x * y = ", z
z = x / y
print *, "z = x / y = ", z
end program ComplexArithmatic
Quando compili ed esegui il programma sopra, produce il seguente risultato:
(9.00000000, 91.0000000)
z = x + y = (12.0000000, 1.00000000)
z = x - y = (2.00000000, 15.0000000)
z = x * y = (91.0000000, -9.00000000)
z = x / y = (-0.283783793, 1.20270276)
La gamma, la precisione e la dimensione dei numeri
L'intervallo sui numeri interi, la precisione e la dimensione dei numeri in virgola mobile dipende dal numero di bit allocati al tipo di dati specifico.
La tabella seguente mostra il numero di bit e l'intervallo per i numeri interi:
Numero di bit | Valore massimo | Motivo |
---|---|---|
64 | 9.223.372.036.854.774.807 | (2 ** 63) –1 |
32 | 2.147.483.647 | (2 ** 31) –1 |
La tabella seguente mostra il numero di bit, il valore più piccolo e più grande e la precisione per i numeri reali.
Numero di bit | Valore massimo | Valore minimo | Precisione |
---|---|---|---|
64 | 0,8 E + 308 | 0,5E – 308 | 15-18 |
32 | 1.7E + 38 | 0.3E – 38 | 6-9 |
I seguenti esempi lo dimostrano:
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e+40
y = 3.73e+40
z = x * y
print *, z
end program rangePrecision
Quando compili ed esegui il programma sopra, produce il seguente risultato:
x = 1.5e+40
1
Error : Real constant overflows its kind at (1)
main.f95:5.12:
y = 3.73e+40
1
Error : Real constant overflows its kind at (1)
Ora usiamo un numero più piccolo -
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e+20
y = 3.73e+20
z = x * y
print *, z
z = x/y
print *, z
end program rangePrecision
Quando compili ed esegui il programma sopra, produce il seguente risultato:
Infinity
0.402144760
Ora guardiamo l'underflow -
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e-30
y = 3.73e-60
z = x * y
print *, z
z = x/y
print *, z
end program rangePrecision
Quando compili ed esegui il programma sopra, produce il seguente risultato:
y = 3.73e-60
1
Warning : Real constant underflows its kind at (1)
Executing the program....
$demo
0.00000000E+00
Infinity
The Kind Specifier
Nella programmazione scientifica, spesso è necessario conoscere la portata e la precisione dei dati della piattaforma hardware su cui si sta lavorando.
La funzione intrinseca kind() consente di interrogare i dettagli delle rappresentazioni dei dati dell'hardware prima di eseguire un programma.
program kindCheck
implicit none
integer :: i
real :: r
complex :: cp
print *,' Integer ', kind(i)
print *,' Real ', kind(r)
print *,' Complex ', kind(cp)
end program kindCheck
Quando compili ed esegui il programma sopra, produce il seguente risultato:
Integer 4
Real 4
Complex 4
Puoi anche controllare il tipo di tutti i tipi di dati:
program checkKind
implicit none
integer :: i
real :: r
character :: c
logical :: lg
complex :: cp
print *,' Integer ', kind(i)
print *,' Real ', kind(r)
print *,' Complex ', kind(cp)
print *,' Character ', kind(c)
print *,' Logical ', kind(lg)
end program checkKind
Quando compili ed esegui il programma sopra, produce il seguente risultato:
Integer 4
Real 4
Complex 4
Character 1
Logical 4