• Non ci sono risultati.

2008/09 Basic Fortran (cont

N/A
N/A
Protected

Academic year: 2021

Condividi "2008/09 Basic Fortran (cont"

Copied!
18
0
0

Testo completo

(1)

Ulteriori elementi di base del linguaggio Fortran Paolo Bison

Fondamenti di Informatica Ingegneria Meccanica

Università di Padova A.A. 2008/09

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.1

Real

 sottoinsieme finito dei reali

 operatori:

+ - * / **

 costanti

sequenza di cifre in notazione decimale (3.5) o scientifica (-1.89E-5)

3.0 6= 3

 rappresentazione finita

 es.

real :: x,y=45.0,z x = y*z

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.2

(2)

Funzioni

 operandi nelle espressioni

R701 primary . ..

or function-reference. ..

R1210 function-reference

is function-name ( [ actual-arg-spec-list ] )

 costituita da un identificatore seguito da una lista di espressioni tra parentesi tonde

 funzioni matematiche sin(x*2)

max(y,3*z,t-u)

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.3

Funzioni intrinseche

 funzioni predefinite nel linguaggio

 matematiche

abs(x) iabs(i) mod(x,y) sqrt(r)

 trigonometriche

cos(r) sin(r) tan(r) acos(r) asin(r) atan(r)

 esponenziale e logaritmo exp(r) log(r) log10(r)

 di conversione int(r) nint(r)

 test tra reali

(0.3333e20 + 1.0e-7 - 0.3333e20) == 1.0e-7 vero o falso?

x == 0.0abs(x)<eps x == yabs(x-y)<eps

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.4

(3)

Zero di una funzione con il metodo della bisezione

x2 x1

y

x y=f(x)

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.5

zero di una funzione

! bisect.f90

! calcolo dello zero della funzione cos con il metodo

! della bisezione

!

program bisect logical :: segnomeno

real :: x0=1.0,x1=2.0,x,EPS=1.0E-3 segnomeno = cos(x0) < 0.0

if ((cos(x1) < 0.0) .eqv. segnomeno) then; stop else

do

x = (x0 + x1) / 2.0

if ((cos(x) < 0.0) .eqv. segnomeno) then x0 = x

else x1 = x end if

if (abs(x0 - x1) < EPS) then; exit; end if end do

print *,x end if

end program bisect

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.6

(4)

Conversione di tipo integerreal

integer :: a real :: x

 implicite - conversione automatica x=a

a=x (troncamento)

 esplicite - funzione per la conversione x=real(a)

a=int(x) troncamento

a=nint(x) arrotondamento = int(x+0.5)

 esempio

a / 2 <=?=> a / 2.0

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.7

Character

 insieme delle stringhe di lunghezza arbitraria0 di

caratteri stampabili

 operatori:

//

 costanti

caratteri tra doppio apice (") "abc" "1" ""

Fortran 90: ’

 char-selector (len=n)

definisce il numero massimo di caratteri

 ordinamento lessicografico per operatori di relazione

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.8

(5)

Character (cont.)

 sottostringhe:

R609 substring

is parent-string ( substring-range ) R611 substring-range

is [ int-expr ] : [ int-expr ]

 funzioni intrinseche

len(s) len_trim(s) trim(s) ichar(c) char(i)

 esempi

character(len=1) :: s0

character(len=10) :: s1="hello",s2 s2="world"

s1 = trim(s1) // " " // s0 s2 = s2(3:5)

s0=char(ichar("3"))

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.9

reverse di una stringa

! reverse.f90

! calcola il reverse di una stringa

!

program reverse integer :: i

character(len=10) :: st,ts read *,st

ts=st(len_trim(st):len_trim(st)) do i=len_trim(st)-1,1,-1

ts = trim(ts) // st(i:i) end do

print *,ts

end program reverse

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.10

(6)

Complex

sottoinsieme finito dei numeri complessi r+ii

operazioni

operatori: + - * / **

funzioni: conjg, abs, sin, cos

costanti

due costanti reali o intere tra parentesi tonde es. (-3,8) (5.7,8.0)

rappresentazione finita

es.

complex :: x,y=(-3.14,5.98),z x = y*sin(z)

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.11

Conversione di tipo integer,realcomplex

integer :: a real :: x complex :: c

 implicite - conversione automatica x=c (parte reale)

a=c (parte reale troncata)

c=x (p.r.valore di x, p.i.0)

c=a (p.r.valore di a, p.i.0)

 esplicite - operatore/funzione per la conversione x=real(c) (parte reale)

x=aimag(c) (parte immaginaria) a=int(c) (parte reale troncata) c=cmplx(a,a)

c=cmplx(x,x) Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.12

(7)

composizione di forze

! sum_forze.f90

! calcola risultante di forze

! rappresentate come numeri complessi

!

program sum_forze

complex :: risultante=(0,0),forza do

read *,forza

if (forza == (0,0)) then; exit; end if risultante = risultante + forza

end do print *

print *,risultante end program sum_forze

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.13

Costanti

 valori che non cambiano durante l’esecuzione

 nome significativo per i valori

 uso come le variabili, eccetto a sx. dell’istruzione di assegnazione

 sintassi:

- attributo parameter della dichiarazione - inizializzazione

- per le stringhe (len=*)

 es.

integer, parameter :: numero_linee=60 real, parameter :: p_greco=3.1415 character(len=*), parameter :: fine="."

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.14

(8)

grafico funzione - 1

! graph.f90

! rappresentazione grafica della funzione

! f(x)=exp(-x)*sin(2*pi*x)

!

! sistema di riferimento

!

! h y y+1

! | | s |

! ---> y

! |

! |

! |- x

! |

! | d

! |

! |

! |- x+1

! |

! |

! V x

!

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.15

grafico funzione - 2

program graph

real, parameter :: d = 0.0625 ! 1/16, 16 linee nell’intervallo

! [x,x+1]

real, parameter :: c = 6.28318 ! 2*pi

integer, parameter :: s = 32 ! 32 caratteri di ampiezza per

!l’intervallo [y,y+1]

integer, parameter :: h = 34 ! posizione dell’asse x integer, parameter :: lim = 32 ! numero di campionamenti

real :: x, y integer :: i, n, k

character (len=2*h) :: linea

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.16

(9)

grafico funzione - 3

do i=0,lim

x = d*i ! calcolo ascissa

y = exp(-x)*sin(c*x) ! calcolo funzione

n = nint(s*y) + h ! calcolo posizione su asse y

! costruzione linea di stampa linea = "" ! stringa vuota do k=0,n-1

if (k==h) then; linea=linea(1:k+1) // "|"

else; linea=linea(1:k+1) // " "

end if end do

linea=linea(1:k+1) // "*" ! k = n

! si continua fino ad h se n<h

! per inserire simbolo asse x do k=n+1,h

if (k==h) then; linea=linea(1:k+1) // "|"

else; linea=linea(1:k+1) // " "

end if end do

print *,linea end do

end program graph

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.17

grafico funzione - 4

*

| *

| *

| *

| *

| *

| *

| *

*

* |

* |

* |

* |

* |

* |

* |

*

| *

| *

| *

| *

| *

| *

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.18

(10)

Selezione multipla

E

S1 S2 SN

L1 L2 LN

 E espressione che ritorna un valore LE

 dato E si esegue la sequenza Si associata all’etichetta

Li = LE

 if LE 6∈ {L1,L2, . . . ,LN} errore o ramo default

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.19

select

selezione multipla

sintassi

R808 case-construct is select-case-stmt

[ case-stmt block ] ...

[ CASE DEFAULT block ] end-select-stmt R809 select-case-stmt

is SELECT CASE ( case-expr ) R810 case-stmt

is CASE case-selector R811 end-select-stmt

is END SELECT

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.20

(11)

select

R812 case-expr is int-expr or char-expr R813 case-selector

is ( case-value-range-list ) R814 case-value-range

is case-value or case-value : or : case-value

or case-value : case-value R815 case-value

is int-initialization-expr or char-initialization-expr

Constraint:For a given case-construct, each case-value shall be of the same type as case-expr. For character type, length differences are allowed.

Constraint: For a given case-construct, the case-value-ranges shall not overlap; that is, there shall be no possible value of the case-expr that matches more than one case-value-range.

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.21

esempi di select

 select case (i) case (1,3,15:20)

k = k*i case default

k=0 end case

 select case (k+z*3) case (:-1)

i=0 case (0)

i=-1 end case

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.22

(12)

conteggio vocali - 1

! conta_voc.f90

! conta il numero di vocali presenti

! in una stringa

!

program conta_voc

integer :: i,n_a=0,n_e=0,n_o=0,n_i=0,n_u=0 character(len=256) :: st

character(len=1) :: ch read *,st

do i=1,len_trim(st)

ch=st(i:i) ! estrae i-esimo carattere if ((ch >= "a") .and.(ch <= "z")) then

ch=char(ichar(ch) - ichar("a")+ ichar("A")) end if

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.23

conteggio vocali - 2

select case (ch) case("A")

n_a=n_a+1 case("E")

n_e=n_e+1 case("I")

n_i=n_i+1 case("O")

n_o=n_o+1 case("U")

n_u=n_u+1 end select end do

print *,"A",n_a,"E",n_e,"I",n_i,"O",n_o,"U",n_u end program conta_voc

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.24

(13)

calculator -1

! calc.f90

!

! programma che calcola espressioni algebriche

! espresse dalla grammatica:

!

! V={0,1,2,3,4,5,6,7,8,9,+,-,=}

! N={<exp>,<num>}

! p={ <exp> ::= <num>= | <num><oper><exp>,

! <num> ::= <cifra> |<cifra><num>,

! <cifra> ::= 0|1|2|3|4|5|6|7|8|9|0

! <oper> ::= +|- }

!

program calc integer :: i

integer :: num1, num2

character (len=100) :: expr character (len=1):: oper,ch

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.25

calculator - 2

read *,expr

print *,"---"

print *,trim(expr) num1=0

oper="+"

i=0 do

i=i+1

if (i>len_trim(expr)) then

print *,"espressione non corretta"; stop end if

ch = expr(i:i)

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.26

(14)

calculator - 3

! lettura numero num2 = 0

if (ch >="0" .and. ch<="9") then do

if (ch >="0" .and. ch<="9") then

num2 = num2*10 +ichar(ch)-ichar("0") i = i+1; ch = expr(i:i)

else exit end if end do else

print *,"espressione non corretta"; stop end if

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.27

calculator - 4

! esegue operazione con numero precedente select case (oper)

case ("+")

num1 = num1 + num2 case ("-")

num1 = num1 - num2 case default

print *,oper," non e’ nel lessico"; stop end select

! in ch c’e’ un operatore o = if (ch=="=") then

print *,num1; stop else

oper=ch end if end do

end program calc

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.28

(15)

Esempi di esecuzione di calc

[paolo@pcbison F]$ ./calc 34+66-87-8=

>

34+66-87-8=

5

[paolo@pcbison F]$ ./calc 7-5%6=

>

7-5%6=

% non e’ nel lessico [paolo@pcbison F]$ ./calc 7

>

7

espressione non corretta [paolo@pcbison F]$ ./calc 56-=

>

56-=

espressione non corretta [paolo@pcbison F]$

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.29

Precisione dei dati

 parametro kind in dichiarazione

 sintassi

(kind=n)

dove n è un numero naturale che indica la precisione

 es.

integer (kind=3) :: i real (kind=8) :: x

 i valori permessi di n e le precisioni associate dipendono dal compilatore

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.30

(16)

Determinazione parametro di kind

 funzioni intrinseche

determinano, se esiste, il numero di kind necessario per rappresentare un dato compreso tra −10r e 10r con p cifre decimali

 selected_int_kind(r)

 selected_real_kind(p,r)

 costante real doppia precisione + funzione intriseca kind

 lettera D per esponente: 1.0D0

 kind(expr)

ritorna numero di kind relativo alla precisione di expr

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.31

programma stampa_kind.f90

! stampa_kind.f90

! stampa numeri di kind

!

program stampa_kind integer :: p,r

print *,"single precision: ",kind(1.0E0) print *,"double precision: ",kind(1.0D0) do

print *,"p r"

read *,p,r if (p==0) then

if (r==0) then; stop; end if print *,selected_int_kind(r) else

print *,selected_real_kind(p,r) end if

end do

end program stampa_kind

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.32

(17)

Uso delle costanti

 uso di identificatori di costanti per il valore di n nell’opzione kind

integer,parameter :: byte=1 integer,parameter :: word=2 integer,parameter :: long=4 integer (kind=byte) :: b integer (kind=long) :: k

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.33

Conversione di precisione

 conversione implicita tutti gli operandi alla massima precisione associata con uno di essi

print *,1.0/3.0 + 1.0D0/3.0 => 0.666666676600774

print *,1.0D0/3.0 + 1.0D0/3.0 => 0.666666666666667

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.34

(18)

singola vs. doppia precisione

singola doppia occ. memoria bassa alta tempo calcolo minore maggiore

 quando doppia?

 dati con valori assoluti minori di 10−39 o maggiori di 1039

 dati di dimensione molto diverse

 dati con differenze molto piccole

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 – p.35

Riferimenti

Documenti correlati

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 –

Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.17. user-defined type

validità di una associazione definita in termini della struttura statica del programma. Introduzione al corso, Paolo Bison, FI08, 2008-12-09

deve ridurre la complessitá convergendo verso un caso base. Ricorsione, Paolo Bison, FI08, 2008-09-29

Fondamenti di Informatica Ingegneria Meccanica. Università di

Fondamenti di Informatica Ingegneria Meccanica. Università di

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.29. Merge sort: codice

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.29. Merge sort: codice