Il 0% ha trovato utile questo documento (0 voti)
45 visualizzazioni30 pagine

Laboratorio Di Programmazione

Caricato da

giulyrandy
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato DOCX, PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
45 visualizzazioni30 pagine

Laboratorio Di Programmazione

Caricato da

giulyrandy
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato DOCX, PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 30

LABORATORIO DI

PROGRAMMAZIONE
L'informatica (INFORmazione autoMATICA), nella sua più moderna accezione, è un campo di
studio molto giovane. I primi veri elaboratori programmabili risalgono infatti solo al 1946, e allora
essa non era considerata una disciplina separata dall'elettronica e dalla matematica.
Nel corso degli anni, con l'incremento delle capacità di calcolo (o computazionali) degli elaboratori
(anche detti per tali motivi computer), ci si rese conto che il compito di "programmare" queste
macchine fosse estremamente difficile e richiedeva teorie e pratiche diverse da quelle dei campi
esistenti. L'informatica, ovvero "la scienza della risoluzione dei problemi con l'aiuto degli
elaboratori", divenne quindi una disciplina autonoma.
L'informatica è una disciplina complessa che abbraccia, come detto, campi molto diversi tra loro,
in cui l'elaboratore elettronico è solo lo strumento mediante il quale si possono attuare le tante
applicazioni per esso pensate. Non a caso il termine informatica deriva dalle parole "informazione"
e "automatica" per sottolinearne caratteristiche e finalità: essa si occupa del trattamento
dell'informazione mediante procedure automatizzabili attraverso un elaboratore. Infatti,
l'informatica è soprattutto la scienza della gestione e dell'elaborazione delle informazioni, e ciò,
spiega perché essa è penetrata in tutte le attività umane rappresentando nei paesi più evoluti
l'infrastruttura fondamentale per lo sviluppo culturale ed economico della società.
In tale ottica l'elaboratore assolve il compito di gestire e memorizzare le informazioni o dati,
mentre l'esperto informatico progetta le applicazioni necessarie a organizzare e quindi elaborare
le informazioni sia mediante l'uso di macchine (tra le quali lo stesso elaboratore), sia facendo
ricorso a sole risorse umane, o infine a soluzioni miste in cui macchine e uomini provvedono alla
attuazione dei processi individuati. A dispetto di quanto molto comunemente si ritiene, quella dei
computer non è però classificabile come "intelligenza": l'elaboratore, infatti, non fa altro che
eseguire istruzioni preventivamente "impartitegli" da un essere umano, ma con una velocità di
calcolo "superiore".

Da questa breve introduzione, emergono quelle che sono le principali problematiche legate
all'utilizzo dell'informatica, che tratteremo nel corso del testo:
 È possibile rappresentare le informazioni in una forma tale da poter essere comprese e
trattate da un computer?
 Come è fatto un computer? È importante conoscerne le componenti fondamentali e
capirne il funzionamento per poterlo utilizzare correttamente?
 Come è possibile "programmare" un computer affinché le procedure di trattamento delle
informazioni siano effettivamente automatizzabili?

INTERAZIONE TRA MATEMATICA E INFORMATICA


Galileo Galilei scrive nel Saggiatore (1624) “La natura è un libro aperto […] scritto con il linguaggio
della matematica. Questo vuol dire che per descrivere la realtà non ci serve altro che costruire
modelli matematici (es. equazione del moto). Possiamo avere sia soluzioni in forma chiusa che
non. Il secondo caso si verifica quando abbiamo matrici a miliardi di righe e colonne che non ci
permettono di fare i calcoli a mano; ed è proprio qui che entra in gioco l’informatica (con il
calcolatore).
Il calcolatore, tuttavia, non riesce a fare calcoli infiniti, quindi bisognerà trovare il risultato
approssimandolo, cercando comunque di fare quanto più possibile per ottenere un risultato
quanto più preciso possibile.

Oggi, la simulazione con il calcolatore affianca la matematica nel suo ruolo di linguaggio per
interpretare la realtà e come strumento per risolvere i problemi derivanti da essa.
Una volta capito quali e quanti passi da fare, creiamo un software/programma che ci permette di
continuare questo problem solving e di risolvere il problema tramite il calcolatore.

Risoluzione di un problema

I passi del nostro problem solving sono i seguenti:

1. Formulazione del problema: precisa definizione delle caratteristiche con individuazione dei
dati di input e di output
2. Descrizione mediante un modello matematico: definizione delle equazioni che
rappresentano il problema
3. Approssimazione mediante un metodo numerico: passaggio dall’infinito al finito
(discretizzazione)
4. Sviluppo dell’algoritmo: precisa definizione delle istruzioni e dei dati per la risoluzione del
problema
5. Sviluppo del programma: traduzione
dell’algoritmo in un linguaggio di
programmazione

Il quarto passo (sviluppo dell’algoritmo) è


quello più importante, che ci dice cosa
dobbiamo fare.
Per comunicare al calcolatore cosa devo fare
bisogna sviluppare un programma (quinto
passo). Questo è un procedimento abbastanza
automatico che ci permette di passare da un
linguaggio di programmazione all’altro:

Più linguaggi vengono


dallo stesso algoritmo

L’insieme delle metodologie per la risoluzione di problemi scientifici con il calcolatore è noto come
CALCOLO SCIENTIFICO (o Analisi Numerica o Calcolo Numerico). Esso, quindi, si occupa di risolvere
un problema matematico (“scientifico”) con il calcolatore (“calcolo”), ossia di fornire idee di base,
metodologie e strumenti hardware e software per la risoluzione del problema matematico con il
calcolatore. Tutto ciò richiede una interazione stretta tra Matematica e Informatica (computer
science).
Per la risoluzione di un problema è necessario ricercare un algoritmo (come scritto prima, il quarto
passo è quello più importante).

Un ALGORITMO è una sequenza di istruzioni elementari, non


ambigue, che risolve un problema in un numero finito di passi,
ossia, in altre parole, è l’insieme di istruzioni che ci porta alla
costruzione delle equazioni. Esso è lo strumento fondamentale
per la matematica computazionale.

N.B. È come una funzione del tipo: Algoritmo --> Risultato

Il calcolatore può fare milioni di miliardi di operazioni al


secondo, ma non infinite, così come non può memorizzare
infiniti numeri.

Inoltre, il risultato può anche essere l’informazione che


l’algoritmo non ha soluzioni.

Il procedimento è costituito da passi ben precisi. Io scrivo


l’algoritmo e l’esecutore di tale algoritmo è il calcolatore. Quindi,
devo scrivere qualcosa che questo esecutore possa
comprendere. Questo “qualcosa” sono istruzioni chiare e non
ambigue.

Dunque, le parole chiave di questa definizione di algoritmo sono:


- Istruzioni elementari
- Non ambiguità
- Finitezza del numero di operazioni

Lo schema mette in luce gli elementi che concorrono alla soluzione dei problemi. Essi sono:
 l'ALGORITMO, ossia un testo che prescrive un insieme finito di operazioni o azioni,
eseguendo le quali è possibile risolvere il problema assegnato. Se si indica con istruzione la
prescrizione di una singola operazione, allora l'algoritmo è un insieme di istruzioni da
svolgere secondo un ordine prefissato;
 l'ESECUTORE, cioè l'uomo o la macchina in grado di risolvere il problema eseguendo
l'algoritmo. Ma se un algoritmo è un insieme di istruzioni da eseguire secondo un ordine
prefissato, allora l'esecutore non solo deve comprendere le singole istruzioni ma deve
essere anche capace di eseguirle. E può eseguirle una dopo l'altra secondo un ordine
rigidamente sequenziale che impone l'inizio dell'esecuzione di una nuova istruzione solo al
termine di quella precedente; oppure può eseguire più istruzioni contemporaneamente
svolgendole in parallelo;
 le INFORMAZIONI DI INGRESSO (anche dette input), ossia le informazioni che devono
essere fornite affinché avvengano le trasformazioni desiderate;
 le INFORMAZIONI DI USCITA (anche dette output), ossia i risultati prodotti dall'esecutore
del dato algoritmo.

Uno dei metodi più diffusi in passato per la descrizione degli algoritmi è il FLOW CHART
(diagramma di flusso). Esso utilizza:
 figure geometriche per identificare il tipo di istruzione;
 archi orientati (frecce) per definire l’ordine delle
istruzioni.

Le figure geometriche sono le seguenti:

 L’inizio e la fine sono definiti da un ovale


 Le istruzioni da eseguire sono incluse in un rettangolo
 Le condizioni da verificare sono incluse in un rombo

Ogni algoritmo ha un unico inizio e un’unica fine.


Ogni istruzione ha un unico arco entrante e un unico arco
uscente.
Ogni rombo ha un unico arco entrante e due archi uscenti.

Una condizione da verificare può essere utilizzata in un duplice


modo: struttura di iterazione o struttura di selezione. Per
scegliere quale istruzione eseguire a seconda della veridicità
della condizione si utilizza una STRUTTURA DI SELEZIONE, caratterizzata da due archi orientati in
uscita verso due direzioni distinte che poi si ricongiungono!

Se una delle condizioni non è sufficientemente specificata è necessario chiedersi come renderla
più chiara, ad esempio ripetendo più volte la stessa istruzione. In questo caso, si utilizza una
STRUTTURA DI ITERAZIONE, che consiste nell’utilizzare una condizione da verificare per ripetere
più volte la stessa istruzione. Quindi, uno degli archi orientati ritorna su istruzioni già eseguite.

Si noti, inoltre, ogni istruzione si può suddividere in


molteplici sotto-istruzioni (anche all’interno della struttura
di selezione – ad esempio, in corrispondenza di V può
esserci un’unica istruzione e in corrispondenza di F ce ne
possono essere 5; le frecce si ricongiungeranno comunque
alla fine). Tale procedimento è detto TECNICA DI
RAFFINAMENTO, una sorta di procedimento a scatole
cinesi.

Ad esempio, l’immagine seguente è la versione finale in


flow chart dell’algoritmo per la macchinetta del caffè:
Quindi, il macro-progetto definisce i sotto-problemi e ogni blocco costituisce l’output (cioè il
dato/risultato) del blocco precedente.

A questo punto, abbiamo una definizione finale di algoritmo:

Un algoritmo è un procedimento per la risoluzione di una classe di problemi, costituito da una


sequenza finita di istruzioni elementari non ambigue da eseguire su un numero finito di dati per
risolvere un problema in un numero finito di passi.

Il termine algoritmo è la latinizzazione di “Al Khwarizmi”, nome di un matematico persiano del IX


secolo, che introdusse la notazione posizionale in occidente. Il suo testo “Hisab Al Jabr wal-
Muqabalah” (“Al Jabr” = algebra) fu tradotto in latino nel XII sec. e rimase il testo di riferimento
per l’algebra in Europa per oltre 300 anni.

Mentre gli antichi romani utilizzavano il SISTEMA ADDITIVO, basato sulla somma di simboli base
che diventavano nuovi numeri), dunque, noi oggi usiamo il SISTEMA POSIZIONALE, per il quale il
valore del numero dipende dalla posizione. Ad esempio, 333  9, ma 333 = 300 + 30 + 3.

Un esecutore di algoritmi deve quindi essere in grado di:


 Immagazzinare dati (di input, intermedi e di output) e istruzioni, ossia ricordarli e
conservarli.
 Effettuare operazioni aritmetiche e logiche sui dati. Le operazioni aritmetiche sono le 4
operazioni base, mentre quelle logiche non sono per i risultati numerici, ma per risposte
del tipo si-no. Effettuare queste operazioni è proprio il ruolo del calcolatore che esegue
l’algoritmo.
 Interpretare ed eseguire istruzioni in un dato ordine. Ovviamente, siamo noi ad adattarci
al linguaggio!
 Interagire con l’esterno, in quanto alla fine dobbiamo avere una risposta/risultato.

Il primo calcolatore programmabile (lo Z1) fu costruito negli anni ’30 del XX secolo dall’ingegnere
tedesco Konrad Zuse (1910-1995).

LA MACCHINA DI VON NEUMANN


Un uomo è un esempio di esecutore di algoritmi. Esso è infatti capace di:
A. Leggere da un libro e scrivere su un quaderno (interazione con l’esterno)
B. Effettuare calcoli a mente o con semplici strumenti (capacità logico / aritmetica)
C. Ricordare dati e istruzioni (capacità di immagazzinare informazioni)
D. Interpretare ed eseguire le istruzioni (capacità di controllo)

In maniera del tutto analoga funziona un calcolatore.

Lo schema fu messo a punto da John Von Neumann, matematico ungherese del XX secolo
emigrato in America nel 1933. Circa nel 1945, elaborò un modello di come doveva essere un
calcolatore. Ovviamente, la tecnologia è cambiata con il passare del tempo, ma le componenti e le
loro utilità sono rimaste le stesse. Questa
struttura influenza i linguaggi di
programmazione, ossia le istruzioni che
diciamo al calcolatore.

I componenti fondamentali della macchina


di Von Neumann sono:
 La Memoria (C)
 L’Unità di Controllo (D)
 L’Unità logico aritmetica (B)
 Le unità di Input e Output (A)

N.B. Von Neumann considerata l’unità di


controllo e l’unità logico-aritmetica come
due entità separate. Oggi, invece, con
l’avanzamento tecnologico, sono
considerate insieme come CPU (Central
Processing Unit).
Nella memoria abbiamo dati e istruzioni. I
dati (numeri) vanno nell’unità aritmetico-logica e le istruzioni vanno nell’unità di controllo.

L’unità di controllo prende le istruzioni dalla memoria e le analizza una per volta. Tali istruzioni
prendono a loro volta un certo dato e lo portalo nell’unità logico-aritmetica.

La CPU, quindi, coordina l’esecuzione delle operazioni fondamentali di un calcolatore.

La memoria contiene l’algoritmo che descrive le operazioni da eseguire e i dati su cui l’algoritmo
stesso opera.

I dispositivi di input e output sono le interfacce della CPU nei confronti del mondo esterno.
Rispettivamente sono l’unità che consente l’inserimento di algoritmo e dati in memoria, e quella
che presenta i risultati dell’attività della CPU.

Queste unità fondamentali formano l’hardware del computer, ossia l’insieme di tutti i componenti
elettronici e meccanici che costituiscono un sistema di elaborazione.

Il prototipo proposto da Von Neumann era basato sul concetto di "programma memorizzato": la
macchina immagazzinava nella propria memoria i dati su cui lavorare e le istruzioni per il suo
funzionamento. Una tale flessibilità operativa fece sì che macchine nate allo scopo di alleviare i
problemi di calcolo per tecnici e scienziati potessero essere in seguito impiegate nella risoluzione
di problemi di natura completamente diversa, come problemi di tipo amministrativo, gestionale e
produttivo.

Le caratteristiche che un sistema di tale tipo presenta, e che ne hanno decretato la rapida
diffusione in molti campi applicativi, sono:
 Uno schema di funzionamento semplice nelle sue linee generali.
 La velocità e affidabilità nella esecuzione degli algoritmi. La velocità di esecuzione si
aggira attualmente sui milioni di istruzioni svolte dalla CPU in un secondo. Dal punto di
vista dell'affidabilità, si può affermare che un computer non commette errori, in quanto è
un esecutore obbediente dell'algoritmo, e gli errori dovuti a guasti o a cattivi
funzionamenti hardware sono subito riscontrabili, alcune volte persino in maniera
automatica.
 Una adeguata capacità di memoria. Per memorizzazione delle informazioni si intende il
compito della memoria di conservare informazioni per la CPU. La memorizzazione può
essere temporanea, permanente o definitiva. Con capacità di memoria si fa riferimento al
numero di informazioni che possono essere gestite e si misura in byte. Tale numero varia in
base al tipo di memoria usato, all'architettura della memoria stessa e al tipo di
informazione.
 Un costo vantaggioso. Per quanto riguarda il costo dei computer si può sicuramente
considerare basso se paragonato ai tempi di lavoro necessari affinché esseri umani portino
a termine gli stessi compiti. Ed è anche in conseguenza di ciò che i computer vanno sempre
più diffondendosi nei settori produttivi della società.

Per concludere si deve notare che i dispositivi di input e di output interfacciano la CPU con
l'ambiente esterno, provvedendo a tutte le trasformazioni necessarie a rendere comprensibili le
informazioni sia alla CPU che agli utenti esterni del
computer. Essi vengono progettati in modo confacente ai
meccanismi di comunicazione delle informazioni
dell'ambiente in cui il computer è immerso. Nelle
comunicazioni con un utente umano, il tipico dispositivo di
input è la tastiera mentre quello di output è uno speciale
televisore detto monitor o video.

Analizziamo ora le componenti della macchina di Von


Neumann una per una.

Memoria

La memoria è il dispositivo per immagazzinare informazioni


(dati e istruzioni) ed è organizzata logicamente come una
lista di LOCAZIONI DI MEMORIA (o Celle di Memoria).

Dal punto di vista tecnologico, è facile realizzare dispositivi


capaci di memorizzare due stati.

Usiamo questo sistema, perché il calcolatore, in quanto


dispositivo elettronico, ha bisogno di informazioni semplici e le informazioni a due stati differenti
sono molto più “immediate” di quelle a dieci stati differenti (in quanto quest’ultimo è anche molto
più incline a errori).

Per tale motivo, ciascuna locazione è composta da un insieme di componenti elementari,


ciascuno dei quali capaci di rappresentare 0 oppure 1, cioè una cifra binaria, anche detta BIT
(contrazione di Binary digIT).
Una locazione di memoria, quindi, è un gruppo di BIT. Si parla di gruppo in quanto un singolo bit
non ci dà molte informazioni. Al contrario, un gruppo di bit ci fornisce tante informazioni quante
sono le possibili combinazioni. Ad esempio, nell’immagine a sinistra è rappresentata una
locazione ad 8 bit, quindi abbiamo 28=256 possibilità.

Per poter accedere rapidamente ai dati presenti in memoria, le locazioni sono univocamente
individuate da un indirizzo.
Per tale motivo, la locazione è la minima quantità di memoria a cui si può accedere. Quindi, invece
di avere un indirizzo per ogni singolo bit, abbiamo un indirizzo per ogni gruppo di bit (ossia per
ogni locazione). Nell’unità logico-aritmetica avremo la somma di bit, uno appartenente ad un
indirizzo e uno appartenente ad un altro.

Nella prima fase dell’era informatica moderna (anni ’50 del XX secolo), ogni azienda strutturava le
locazioni di memoria con un numero di bit differente dalle altre. La conseguenza furono grandi
problemi di portabilità delle applicazioni da un calcolatore all’altro. Sorse, infatti, l’esigenza di
uniformare la dimensione delle locazioni di memoria. Oggi, la dimensione comune delle locazioni
di memoria di tutti i calcolatori è 8 bit, cioè 1 Byte, che è diventata proprio l’unità di misura della
capacità di memoria.

Con una sola locazione è possibile memorizzare una quantità di informazione molto piccola per le
esigenze concrete. Ad esempio, con 8 bit è possibile memorizzare:
 un numero intero (con segno) minore di 128;
 una lettera dell’alfabeto o un carattere.

Per tale motivo, le locazioni sono raggruppate in PAROLE o WORD. Tipicamente, oggi i calcolatori
hanno parole di:
 32 bit (cioè 4 locazioni)
 64 bit (cioè 8 locazioni)
 128 bit (cioè 16 locazioni)

Ovviamente, più ne mettiamo, più spazio occupiamo, più tempo ci metteremo.


N.B. Gruppo di bit = Locazione. Gruppo di locazioni = Parola

Sulle locazioni di memoria non possiamo fare le operazioni aritmetiche, in quanto siamo nella
memoria e non nell’unità logico-aritmetica. Al contrario, è possibile effettuare altri due tipi di
operazioni:
 LETTURA. Consiste nel prelevare un dato dalla memoria (ad esempio per utilizzarlo in una
somma). L’operazione è conservativa (il dato rimane nella locazione di memoria, e quando
lo “spostiamo” nell’unità aritmetico-logica, non scompare dalla memoria, ma ne viene fatta
una copia).
 SCRITTURA. Consiste nel mettere un dato in una locazione di memoria (ad esempio per
memorizzare un dato di input). L’operazione è distruttiva (un eventuale dato già presente
si perde).

Da un punto di visto logico, qualunque dispositivo capace di memorizzare dati o istruzioni è una
memoria. Dal punto di vista pratico, in un calcolatore esistono diversi tipi di memoria, con
caratteristiche e funzioni diverse. Si è creata, dunque, una gerarchia di memoria.
Con l’avanzare della tecnologia, si sono aggiunti vari tipi di memoria (intesa come dispositivo per
ricordare). Esse non sono alternative tra loro, ma complementari.
Ognuna ha una funzione ben precisa e tutte servono ad immagazzinare e ricordare dati (byte).

In questa gerarchia, i vari tipi di memoria sono ordinati dal più piccolo al più grande e dal più
veloce al più lento.

Ogni livello è cache per il livello sottostante.


Descriviamo brevemente queste memorie.

 I registri CPU e la Cache si occupano di portare i dati che sono più spesso richiesti
dall’algoritmo all’interno della memoria, in modo da poter essere riutilizzati il più possibile,
senza doverlo andare a recuperare ogni volta.
 La Memoria Centrale (ad esempio
RAM, ossia Random Access Memory) è
veloce, piccola e volatile (cioè si perde
tutto quando si stacca dal calcolatore).
 L’Hard Disk (o Disco Fisso, o Memoria
Secondaria) è lenta, grande e
permanente. Tutti i programmi
risiedono sulla memoria secondaria e
quando bisogna eseguire un
particolare programma viene spostato
sulla memoria centrale (più veloce).

Le principali caratteristiche che differenziano


le varie memorie sono il tempo di accesso e
la dimensione:
 ALTO LIVELLO  Registri CPU, Cache,
Memoria centrale
 BASSO LIVELLO  Hard disk, Memorie terziarie

Il costo della memoria è proporzionale


alla loro grandezza e velocità.

In altre parole, il costo è proporzionale a:

N ∙V o equivalentemente N /T

Dove:
• N è la dimensione in byte
• V è la velocità
• T è il tempo di accesso
CPU (Central Processing Unit)

La CPU contiene i dispositivi elettronici in grado di acquistare, interpretare ed eseguire il


programma contenuto nella memoria centrale, operando la trasformazione dei dati.

La caratteristica principale della CPU è il numero di azioni (istruzioni o operazioni) eseguite


nell’unità di tempo. Questa caratteristica è proprio definita PRESTAZIONE della CPU e la sua unità
di misura è l’hertz: Hz = 1/sec.

Il processore centrale è composto da tre parti fondamentali: l’Unità di Controllo (UC o CU – Control
Unit), l’Unità Logico-Aritmetica (ALU) e un insieme di registri detti “interni” per distinguerli da
quelli della memoria centrale, che variano da processore a processore in funzione della sua
architettura.

Unità di Controllo (CU)


L'unità di controllo della CPU è l'organo preposto all'interpretazione delle singole
istruzioni e all'attivazione di tutti i meccanismi necessari al loro espletamento. In
particolare, la CU ha il compito di prelevare ogni istruzione dalla memoria centrale, di
decodificarla, di prelevare i dati dalla memoria
se servono all'istruzione, e infine di eseguire
l'istruzione.
Per esempio: se l'istruzione prelevata è di tipo
aritmetico e richiede due operandi, la CU
predispone dapprima il prelievo dalla memoria di
tali operandi, poi attiva l'ALU affinché esegua
l'operazione desiderata, e infine deposita il risultato
di nuovo in memoria. Al termine dell'esecuzione di
una istruzione, la CU procede al prelievo dalla
memoria della successiva istruzione secondo un
ordine rigidamente sequenziale: ossia l'esecuzione
di una istruzione può avere inizio solo se la
precedente è stata portata a termine.

Perché l'intero sistema possa avere avvio, la CU


deve essere informata dell'indirizzo del registro
di memoria che contiene la prima istruzione da
eseguire. A partire da questa operazione iniziale,
detta di boot, la CU esegue ininterrottamente l'algoritmo detto “ciclo del processore”
fino allo spegnimento del sistema. Le tre fasi del ciclo vengono anche dette fasi di fetch
(prelievo dell'istruzione dalla memoria centrale), operand assembly (decodifica
dell'istruzione con preparazione degli operandi) ed execute (esecuzione ed eventuale
memorizzazione del risultato).

L’unità di controllo coordina tutte le attività del calcolatore:


 operazione iniziale di boot
 preleva dalla memoria le istruzioni (fetch),
 le interpreta (decode o operand
assembly),
 preleva i dati dalla memoria (load),
 esegue l’istruzione (execute),
 memorizza il risultato (store),
 determina la successiva istruzione da
eseguire.

Le fasi di fetch, decode e execute sono le tre fasi


centrali del ciclo del processore.
Se la fase di execute prevede la memorizzazione
del risultato dell'elaborazione in memoria centrale,
la corrispondente sottofase di scrittura prende
anche il nome di write back.

Unità logico-aritmetica (ALM)


Durante le sue elaborazioni la CU può depositare informazioni nei suoi registri interni in quanto
sono più facilmente individuabili e hanno tempi di accesso inferiori a quelli dei registri della
memoria centrale. Numero e tipo di tali registri variano, come già detto, a seconda
dell'architettura della CPU.
In questi registri della CPU, i dati possono essere elaborati velocemente nel caso in cui servissero
più volte.

L’ALM esegue le operazioni logiche e aritmetiche, eseguendo i comandi provenienti dall’unità di


controllo.

Registri
Sono le locazioni di memoria della Cache.

Unità di Input e Output

Sono le interfacce del calcolatore con il mondo esterno.

 Consente l’interazione con l’uomo (video, tastiera, stampante, mouse)


 Consente l’accesso alle reti
 Si preoccupa di convertire i dati in formato binario
 Trasferisce dati da e per la memoria
Cioè, sono i dispositivi che permettono di fornire e ricevere dati.

Colui che formalizzò il concetto di algoritmo e di macchina programmabile (la Macchina di Turing)
nel 1936 fu il matematico inglese Alan Turing (1912-1954), che negli anni ’50 pose le basi
dell’Intelligenza Artificiale.

RAPPRESENTAZIONE DEI DATI


Abbiamo visto che la macchina di Von Neumann è uno schema dell’architettura del calcolatore,
nella cui memoria sono appunto memorizzati dati e istruzioni.

Come sono rappresentate in memoria tale informazioni?

Analizziamo prima di tutto il concetto di informazione. Spesso, si attribuisce al termine


"informazione" un senso molto generico: esso deriva da informare, ossia dare forma, e fa
riferimento a un concetto astratto, che può coincidere con qualunque notizia o racconto. In
termini molto semplici si può dire che l'informazione è qualcosa che viene comunicato in una
qualsiasi forma scritta o orale. Essa non coincide con il concetto di dato. I dati da soli, in realtà,
non hanno nessun significato, ma possono fornire informazioni se interpretati e opportunamente
correlati.

DEFINIZIONE: Per tipo di dato si intende una classificazione che definisce:


 i possibili valori che un certo dato può assumere,
 le operazioni che possono essere fatte su quel dato,
 il significato in memoria di quel dato.

I tipi di dato elementari sono:


1. il tipo intero
2. il tipo alfanumerico
3. il tipo logico
4. il tipo reale

Ovviamente, possono anche esserci dati più complessi, ma comunque riconducibili a questi
elementari.

Il tipo intero (1)

Schema riepilogativo:
Il sottoinsieme dei numeri relativi (interi positivi e negativi) che possono essere rappresentati nella
memoria di un calcolatore. In generale, nella rappresentazione posizionale, le cifre di un numero
dono i coefficienti di una combinazione lineare delle potenze della base.
Ad esempio, dato il numero 123 in base b=10, otteniamo che 123=1∙ 102 +2∙ 101 +3+10 0.

Questo tipo di dato ci serve per contare (ad esempio, il numero di elementi in un insieme, oppure
il numero di passi, e così via). Invece, per misurare, ci vorrebbero i numeri decimali.

Nella memoria del calcolatore, poiché le locazioni di memoria sono costituite da bit, i dati di tipo
intero sono rappresentati col sistema posizionale binario (base b=2).

Rappresentazione binaria pura (unsigned)

CONVERSIONE DA BASE 2 A BASE 10


Dato il numero 10010 in base 2, otteniamo che esso, in base 10, è 18. Infatti:

4 3 2 1 0
10010=1∙ 2 +0 ∙ 2 +0 ∙2 +1 ∙2 +0 ∙ 2 =16+ 2=18

Essendo in una locazione di memoria, il numero in base 2 deve essere ad 8 cifre (deve, cioè,
occupare 8 posti). Nel caso di 11010 notiamo che ci mancano ancora 3 posti, per cui possiamo
considerarli come 3 zeri prima del numero, i quali, come per la rappresentazione in base 10, non
hanno valore. Ad esempio, 02 = 2, e allo stesso modo 00010010 = 10010.
L’unità di output fa questa conversione automaticamente.

CONVERSIONE DA BASE 10 A BASE 2


In questo caso si effettuano successive divisioni per la base b=2 fino ad ottenere quoziente 0 e si
prendono i resti in ordine inverso.

18 / 2 = 9 con resto 0
Prendo il risultato precedente e continuo:
9 / 2 = 4 con resto 1
Itero questo procedimento:
4 / 2 = 2 con resto 0
Infine:
2 / 2 = 1 con resto 0
1 / 2 = 0 con resto 1

Il numero in forma binaria che cerchiamo


è la successione ordinata dei resti dall’ultima divisione alla prima.

L’unità di input fa questa conversione automaticamente.

Le operazioni di addizione e moltiplicazione si svolgono secondo le normali regole aritmetiche.

La limitazione dello spazio implica un massimo e un minimo rappresentabile: 0 ≤ K ≤ 255 .


, dove K è un numero intero rappresentato con 8 bit.

Più in generale, dati L bit, abbiamo che: 0 ≤ K ≤ 2 L−1 . Infatti, dato L = 8, 28−1=255.

• Rappresentazione segno e modulo

In questo caso è assegnato al primo bit della locazione il segno: 1 = – e 0 = + .

Quindi, a questo punto, abbiamo solo 7 bit su 8 per la rappresentazione del modulo. Dunque,
l’intero K rappresentabile su 8 bit sarà: −127 ≤ K ≤ 127 .

Più in generale, dati L bit, abbiamo che: −( 2 L−1−1 ) ≤ K ≤2 L−1−1 . Infatti, 27−1=127.

Tale rappresentazione, tuttavia, non permette di effettuare la sottrazione come somma algebrica
tra numeri di segno opposto: X −Y ≠ X+(−Y ).
Inoltre, abbiamo detto che con la rappresentazione segno e modulo, per convenzione, attribuiamo
l’ultimo bit sulla sinistra al segno e i rimanenti alla rappresentazione del modulo. Il problema sorge
quando dobbiamo rappresentare lo 0 (che è sia positivo sia negativo, per definizione):

• Rappresentazione complemento a 2

I numeri positivi sono rappresentati come con la rappresentazione unsigned, utilizzando al più L-1
bit.
I numeri negativi, invece, sono rappresentati in due passi:
 si cambiano i bit 0 in 1 e viceversa della rappresentazione del valore assoluto;
 si aggiunge 1 al risultato.
CONVERSIONE DA DECIMALE IN BINARIO
 numero positivo: rappresentazione unsigned (da base 10 a base 2) di al più L – 1 bit
 numero negativo:
1. cambio dei bit 0 con 1 e viceversa (complemento a 1)
2. si aggiunge di 1

CONVERSIONE DA BINARIO IN DECIMALE


 numero positivo (1° bit = 0): rappresentazione unsigned (da base 2 a base 10)
 numero negativo (1° bit = 1):
1. si sottrae 1
2. complemento a 1

Con questa rappresentazione è possibile eseguire la differenza come somma algebrica di numeri di
segno opposto.

La seguente è l’unica rappresentazione dello zero:

0 0 0 0 0 0 0 0

Un numero k, con L=8 bit, è rappresentabile se −128 ≤ K ≤ 127 . Più in generale, dati L bit, abbiamo
che: −2 L−1 ≤ K ≤ 2L−1−1.

Inoltre, è possibile interpretare la rappresentazione in


maniera “circolare”, dove gli opposti sono simmetrici
rispetto all’asse verticale (a sinistra i negativi e a destra i
positivi):

• Rappresentazione per eccesso

Fissiamo un eccesso S ∈ Z e, a partire dalla rappresentazione unsigned, si mappa l’intervallo


[−S ; S−1] sull’intervallo [0 ; 255].

Avviene, dunque, una traslazione, dato K ∈[−128 ,127 ]:

CONVERSIONE DA DECIMALE IN BINARIO


 Si aggiunge 128 a K
 Si rappresenta unsigned
CONVERSIONE DA BINARIO IN DECIMALE
 Si effettua la conversione unsigned
 Si sottrae 128 a K

Il primo bit di un numero negativo è sempre 0, ma non deve essere visto come segno.

Con questa rappresentazione è possibile eseguire la differenza come somma algebrica di numeri di
segno opposto.

La seguente è l’unica rappresentazione dello zero:

0 0 0 0 0 0 0 0

Un numero k, con L=8 bit, è rappresentabile se −128 ≤ K ≤ 127 . Più in generale, dati L bit, abbiamo
che: −2 L−1 ≤ K ≤ 2L−1−1.

Inoltre, anche la rappresentazione per eccesso ha


un’interpretazione circolare.

Infine, la rappresentazione per eccesso e per


complemento a 2 coincidono a meno del bit del segno:

Riepilogo:

= +0
= –0

=0 = –127 = –128 = –128

= 255 = 127 = 127 = 127


Sul tipo di dato intero sono definite le tradizionali operazioni aritmetiche: addizione, sottrazione,
moltiplicazione e divisione.

Poiché nella rappresentazione del tipo intero non è previsto il punto decimale, la divisione tra
numeri interi produce sempre un numero intero per troncamento. Quindi, dichiarando all’inizio
che vogliamo solo il quoziente, ossia che siamo in Z , il resto viene scartato dal risultato.

La situazione per cui il risultato di una operazione tra due numeri rappresentabili non è
rappresentabile è detta OVEWFLOW. Questo, quindi, è il fenomeno che si verifica quando
cerchiamo di rappresentare un numero che va al di fuori dell’intervallo di rappresentabilità.

ATTENZIONE! Alcune proprietà dell’aritmetica non valgono:

(perché 60+70 non lo è)

Il tipo carattere

Schema riepilogativo:

CODICE : simboli ( = elementi atomici della rappresentazione)

CODIFICA : trasformazione da simboli a bit

STRINGHE : “parole-codice” ( = possibili sequenze di simboli)

LINGUAGGIO : insieme di regole per stabilire quali parole hanno senso e quali non e per
combinarle in modo corretto.

Tutte sono “sottocategorie” e parti del codice


• Rappresentazione di dati alfanumerici – codice ASCII

Tra lettere, cifre e caratteri speciali, i dati alfanumerici sono circa un centinaio e servono circa 7-8
bit per rappresentare ognuno di essi. Per tale motivo, se si ha necessità di memorizzare più
caratteri, si concatenano più locazioni di memoria. American Standard Code for Information Interchange

Le operazioni possibili sono:

 Confronto

Esso segue l’ordine alfabetico, conservati


dal codice ASCII.

 Concatenazione

ESEMPIO. pesce//cane = pescecane

Ovviamente, questi tipi di operazioni non


sono definiti sui caratteri strettamente
numerici.

N.B. La stessa stringa ha significato diverso


se interpretata come tipo di dato intero o
carattere.

• Rappresentazione di dati logici

Si utilizza nella verifica delle veridicità di una proposizione, infatti è


l’insieme costituito dagli elementi  vero ; falso .

Per rappresentare questi due valori sarebbe sufficiente un solo bit,


ma per completare una locazione di memoria, si riempie l’ultimo
bit della locazione, lasciando gli altri 7 come 0.

Le operazioni possibili sono:

 Negazione : agisce su un dato cambiandone il valore. Viene


indicata con not.

 Congiunzione : agisce su due dati ed è vera solo se entrambi


i dati sono veri. Viene indicata con and.
 Disgiunzione : agisce su due dati ed è vera se almeno
uno dei dati è vero. Viene indicata con or.

In un’espressione logica le operazioni vengono eseguite nel


seguente ordine:
1. NOT
2. AND
3. OR

È possibile alterare l’ordine mediante le parentesi e valgono le FORMULE DI DE MORGAN:


 NOT(PANDQ)=NOTP OR NOTQ
 Q NOT(PORQ)=NOTP AND NOTQ

Esiste una
naturale
corrispondenza
tra i valori vero-
falso con i valori
0-1, attraverso la
quale è possibile
interpretare le
operazioni
aritmetiche tra
numeri binari come operazioni logiche.

Il tipo reale – Rappresentazione IEEE

In generale, abbiamo la rappresentazione floating point normalizzata (ES. 0,3746 ∙ 102):

e
x=f ∙ b
Dove:
 b ∈ N : b>1
 e∈Z
 1/b ≤|f |<1, cioè la parte intera di f è sempre uguale a zero e la sua prima cifra decimale è
non nulla

La rappresentazione floating point di x è indicata con fl(x ),


che si riferisce al punto che si sposta.

L’immagine a lato mostra come rappresentare un dato di


tipo reale in memoria: è necessario rappresentare
separatamente mantissa ed esponente (ed i rispettivi segni).
La mantissa è la parte decimale di f e e è l’esponente.

Ovviamente, la rappresentabilità di un dato di tipo reale dipende dalla lunghezza della parola, per
cui abbiamo un vincolo sia sul numero di cifre della mantissa, sia su quello dell’esponente.

Abbiamo, infatti, una precisione finita per la mantissa,


che indicheremo con t . Questo vuol dire che tutti i numeri
con più di t cifre non possono essere rappresentati
esattamente. Quindi, abbiamo:
t= precisione del sistema aritmetico

Se il numero di mantissa supera questo valore, allora si


rappresenta x con un numero macchina vicino, tramite:

 Troncamento: si eliminano le cifre decimali in eccesso. (Rimane uguale, ignorando l’ultimo


bit)
 Arrotondamento: si approssima x con il numero macchina più vicino. (Approssimazione)

Invece, abbiamo un range limitato per l’esponente, al di fuori del quale gli esponenti non posso
essere rappresentati esattamente. Chiamiamo b la base e q il numero di cifre a disposizione per le
cifre dell’esponente, allora:

q−1
Emin =−(b −1)=minimo esponente rappresentabile
q−1
 Emax =b −1=massimo esponente rappresentabile

Per cui, il nostro range sarà il seguente:


Emin ≤e ≤ E max

In particolare, l’intervallo di
rappresentabilità di un numero reale è:

−5 5
0.100 ∙ 10 ≤ R ≤ 0.999 ∙10

Dove, 0.999 ∙ 105 è la soglia dell’overflow


L’insieme finito dei numeri reali esattamente
rappresentabili è detto Insieme dei numeri
macchina.
I quattro parametri (b , q , E max , E min) da cui esso
è caratterizzato, invece, sono detti costanti
macchina del sistema aritmetico floating
point a precisione finita.

Dunque, riassumendo, l’intervallo di rappresentabilità è:


Nel 1989 viene definito lo standard IEEE 754 che costituisce il formato di rappresentazione floating
point più diffuso.

Il primo bit della mantissa è sempre uguale a 1, e per tale motivo si sottintende (guadagnando un
bit di precisione). È il cosiddetto bit implicito.

In questa rappresentazione, inoltre, l’esponente è rappresentato come intero per eccesso 127,
cosa che trasforma l’intervallo [0 ,255 ] nell’intervallo [−127 ,128 ].

In realtà gli esponenti rappresentabili nell’aritmetica standard IEEE appartengono all’intervallo


[−126 ,127 ], in quanto gli esponenti -127 (corrispondente a 00000000) e 128 (corrispondente a
11111111) vengono usati per gestire situazioni eccezionali (e=0 ; numeri denormalizzati, cioè bit
implicito nullo ; e=255 ; infinito e forme indeterminate).

OPERAZIONI

Le operazioni possibili sono addizione fl.p., sottrazione fl.p., moltiplicazione fl.p., divisione fl.p.

Analogamente al tipo di dato intero il risultato è definito solo se:


 Gli operandi sono rappresentabili,
 Il risultato è rappresentabile.

ERRORI DI ROUND-OFF
Uno dei problemi del calcolo scientifico è valutare l’accuratezza del risultato calcolato da un
algoritmo e la risoluzione di un problema scientifico è soggetta a numerosi tipi di errore.

Distinguiamo, in particolare, due tipi di errori.

Errore assoluto
Sia x un numero reale qualunque e x ¿ una sua approssimazione corretta a m cifre decimali. Allora,

¿ −m
E A =¿ x−x ∨¿ 10

L’errore assoluto fornisce informazioni sulle cifre decimali esatte.

Ma non vale il viceversa, in quanto non è detto che se l’errore è minore di 10−m allora ho sempre
m cifre decimali corrette.

Errore relativo
¿
Sia x un numero reale qualunque e x una sua approssimazione corretta a m cifre significative:
E R=| x−x |/¿ x∨¿ 10
¿ −m+1

L’errore relativo fornisce informazioni sulle cifre significative esatte.

Quindi, l’errore relativo ci fornisce un modo per tenere conto dell’ordine di grandezza del numero
da approssimare.

ERRORE RELATIVO DI ROUND-OFF

Ovviamente, l’approssimazione di x che possiamo usare è anche quella floating point, per cui:
¿
x =fl ( x).

Ci chiediamo, allora, qual è il massimo errore relativo che si commette rappresentando x con fl(x )
? Esso è detto Massima Accuratezza Relativa (è una delle costanti macchina) e si indica/calcola nel
seguente modo:

u=max {|
x−fl(x )
x |}
≤ b1−t /2

fl ( x )−x
Inoltre, posto δ= ⟹ fl ( x )=x (1+δ), con ¿ δ∨≤ u.
x

ERRORE RELATIVO NELLE OPERAZIONI

I seguenti sono i passi che caratterizzano la somma floating point:


In questo caso, non valgono:
 la proprietà associativa dell’addizione
 la proprietà distributiva della moltiplicazione rispetto all’addizione

Studiamo ora, invece, l’errore relativo di round-off commesso nel calcolatore:

E R=| z ||
z−fl(z ) ( x Op y )−(x Opfp y)
=
x Op y |≤b 1−t /2=u
Dove:
 +¿ fp ¿ è la somma eseguita dal calcolatore (somma floating point)

| |
¿
¿ z−z
 fl ( z )=fl ( x + y )= x +¿ fp y=z ⟹ E R= =¿ ¿
z

 Op

un’operazione aritmetica
 Opfp la sua corrispondente operazione in aritmetica a precisione finita
 ( x Opfp y ) =(x Op y )(1+δ), con ¿ δ∨≤ u
Epsilon macchina

In un sistema aritmetico floating point esiste un insieme di numeri che fornisce contributo alla
somma con 1.

Infatti, ∃ x :1+¿ fp x=fl ( 1+ x )=1 ¿.

Quindi, definiamo epsilon macchina: min ε :1 +¿ fp ε =fl ( 1+ ε ) >1 ¿.

Si verifica facilmente che: ε =u=b1−t /2.

ALGORITMO PER IL CALCOLO DELL’EPSILON MACCHINA

Conoscere ε equivale a conoscere t.

Un modo per calcolare ε è basato su un algoritmo iterativo che ad ogni passo:


 divide un valore a per 2
 verifica se 1+a> 1

La procedura non ha parametri di input e restituisce il valore dell’epsilon macchina.

Più in generale, dato x >0, dobbiamo calcolare: min y : x+ y=fl (x + y )> x .

Dividendo per x, si ottiene: 1+ y / x=fl(1+ y /x )> 1. In questo modo ci si riconduce alla definizione
di epsilon macchina: y / x=ε ⟹ y=ε∨x ∨¿.

1 1−t
A livello pratico, dati i valori di input di b , t , E min , E max , x , calcoliamo ε = b , ricordando che
2

( ) δ
fl ( x+ δ ) > x ⟹ fl 1+ > x ⟹ δ=ε ∙ x .
x

LINGUAGGIO PASCAL-LIKE / FORTRAN

PASCAL-LIKE FORTRAN

Inizio algoritmo begin |nome algoritmo| program |nome algoritmo|

Dichiarazione variabili Implicit none


var |variabile|: |tipo di variabile| |tipo di variabile| :: |variabile|

(real/integer/character/logical) (real/integer/character/logical)
(+ complex)
Dichiarazione array var |variabile|(N): array of |tipo |tipo di variabile|, dimension
di variabile| (N) :: |variabile|

, dove N è la dimensione , dove N è la dimensione

Lettura read |variabile| read*, |variabile|

per la lettura di array, si usa la per la lettura di array, si usa la


struttura di selezione struttura di selezione

Commento (|commento|) ! |commento|

Assegnazione = =

Struttura di iterazione if (|condizione|) then if (|condizione|) then


|istruzione| |istruzione|
else else
|istruzione| |istruzione|
endif endif

oppure oppure

repeat do
|istruzione| |istruzione|
until (|condizione|) if (|condizione|) exit ; enddo

oppure oppure

while (|condizione|) do while (|condizione|)


|istruzione| |istruzione|
endiwhile enddo

Struttura di selezione for (|condizione|) do (|condizione|)


|istruzione| |istruzione|
endfor enddo

Stampa risultato print |risultato| print*, |risultato|

per la stampa di array, si usa la per la stampa di array, si usa la


struttura di selezione struttura di selezione

Fine programma end |nome algoritmo| end


N.B. Se bisogna
scrivere operazioni
logiche nel linguaggio
fortran, è necessario
scriverle tra due punti:
.and. ; .or. ; . not.

SISTEMA OPERATIVO LINUX

Alcune

denominazioni importanti:
Oltre all’interfaccia grafica (desktop) fornita dalla distribuzione, LINUX possiede un’interfaccia “a
line di comando”, che prende il nome di SHELL (guscio), detto anche terminale.

La shell è la sola interfaccia utilizzabile quando si opera su sistemi remoti, infatti attraverso la shell
l’utente è in grado di agire sui file e le directory, in quanto essa avvisa l’utente che è pronta per
accettare un comando visualizzando una stringa chiamata prompt: >> |comando|.

COMANDI
/ Root directory

~ Home directory (fissa)

. Working directory

.. Directory di livello superiore a quella corrente


di lavoro

>> pwd Visualizza la directory corrente di lavoro

(pwd = print working directory) Sono mostrate tutte le directory, dalla root
directory alla working directory, separate da “/

ls Visualizza il contenuto della working directory

(ls = LiSt)

ls directory Visualizza il contenuto della directory


specificata

ls -l Visualizza ulteriori informazioni

cd nome Cambia la directory corrente di lavoro in quella


specificata
(cd = Change Directory)

cd .. Cambia la directory in quella di livello


superiore

cd Cambia la directory corrente nella home


directory

mkdir |nome directory| Crea una nuova directory con il nome


specificato
(mkdir = MaKe DIRectory)
Errore: se già esiste file/directory con il nome
specificato

rmdir |nome directory| Elimina la directory esistente di cui è


specificato il nome
(rmdir = ReMove DIRectory)
Errore: se la directory specificata non è vuota

gedit |nome programma/file|.f90 • Crea un nuovo programma con il nome


specificato

• Apre il file specificato, se già esistenze

N.B. gedit è l’editor dell’interfaccia grafica e


non può essere utilizzato su sistemi remoti.
Editor della shell sono: vi ed emacs

cp |nome file| |nome file / directory| • Crea una copia del file esistente specificato e
lo sovrascrive ad un vecchio file specificato
(cp = CoPy)
• Crea una copia del file esistente specificato
nella directory specificata, utilizzando lo stesso
nome

mv |nome file vecchio| |nome nuovo / • Sposta un file esistente di cui è specificato il
directory| nome nella directory specificata

(mv = MoVe) • Rinomina il file esistente specificato con il


nuovo nome specificato

rm |nome file|.f90 Elimina un file esistente, di cui è specificato il


nome
(rm = ReMove)

cat |nome file|.f90 Mostra il contenuto del file specificato


gfortran |nome programma|.f90 • Per compilare il programma FORTRAN
specificato

• Segnala eventuali errori di sintassi

cc |nome programma|.c • Per compilare il programma C specificato

• Segnala eventuali errori di sintassi

./a.out Per inserire i dati di input all’algoritmo appena


programmato. Prodotto direttamente da
gfortran o da cc se non ci sono errori.

Sia gfortran che cc operano in due fasi:


1. compilazione separata dei singoli file che compongono il programma, chiamati file oggetto;
2. collegamento (linking) dei file oggetto con le librerie

Potrebbero piacerti anche