Sei sulla pagina 1di 43

•Legati al concetto di algoritmo sono l’esecutore e il progettista dell’algoritmo.

•La necessità di una comunicazione tra progettista ed esecutore implica che la descrizione
debba essere fatta in un linguaggio comprensibile dall’esecutore.
•Un algoritmo è dunque scritto in termini di operazioni elementari che l’esecutore può
comprendere immediatamente, e che è in grado di eseguire, in una certa quantità di tempo e
con un effetto ben preciso.
•L’esecuzione di queste operazioni nella sequenza ordinata stabilita dall’algoritmo consente
all’esecutore di risolvere un problema (o un insieme di problemi, uno alla volta).
•Il numero di queste operazioni (istruzioni) contenute nell’algoritmo, per quanto grande, deve
essere finito, perché l’esecuzione deve finire (non importa quando), o il problema non si potrà
mai considerare risolto.

- Algoritmo-esempio:
PROBLEMA: preparare un caffè
ALGORITMO (che genera la soluzione al problema)
1.metti acqua in A fino alla valvola
2.metti B in A
Questo è un 3.riempi B di caffè
algoritmo
4.metti C su A
descritto con un
5.avvita C
linguaggio
naturale 6.Mettere l’oggetto montato su un fornello
7.Accendere il fornello
8.Aspettare che l’acqua finisca di uscire in C
9.Spegnere il fornello

In generale un algoritmo deve essere scritto in un Perché l’algoritmo sia efficace, è sempre opportuno che
linguaggio comprensibile dall’esecutore scelto o il linguaggio sia formale e ben definito, per non
che è a disposizione incorrere per esempio in ambiguità o ridondanza.

- Sistema di calcolo
MOLTO GENERALMENTE:
• Un calcolatore è una macchina per l’esecuzione di algoritmi in maniera automatica.
• Deve essere in grado di memorizzare dati e di eseguire su di essi un certo numero di operazioni, per ottenere altri dati.
• Un’operazione viene eseguita solo se il calcolatore riceve il comando di esecuzione di un’operazione, detto istruzione.

• Un sistema di calcolo si compone di almeno due livelli (a loro volta decomponibili in altri livelli):
•Hardware: componenti elettroniche, meccaniche, ottiche, fisiche in generale...
•Software: insieme di programmi (sistema operativo e applicazioni).

• Chi usa un sistema di calcolo interagisce con esso attraverso il livello più alto, cioè quello Software:
•L’utente utilizza applicazioni;
•Il sistema operativo nasconde tutto ciò che avviene, al punto che l’utente può anche non sapere a che livello
vengono eseguite le operazioni che richiede e in quante altre vengono eventualmente scomposte.
•Un UOMO è un esempio di esecutore di algoritmi sa:
-Leggere da un libro e scrivere su un quaderno (interazione con l’esterno)
-Effettuare calcoli a mente o con semplici strumenti (capacità logico/aritmetica)
-Interpretare ed eseguire le istruzioni (capacità di controllo)
-Ricordare dati e istruzioni (capacità di immagazzinare informazioni)

• Per eseguire un algoritmo, il calcolatore deve saper:

•interagire con l’esterno,

•immagazzinare informazioni (dati e istruzioni),

•effettuare operazioni logiche e aritmetiche,

•interpretare ed eseguire istruzioni.

• Un calcolatore moderno comprende:


 (almeno) una unità di input e una di output (interazione Input: tastiera, microfono, sensori, il touchscreen...
con l’esterno) Output: schermo, stampante, altoparlanti…

 (almeno) una unità logico/aritmetica per eseguire i calcoli (capacità logico/aritmetica) →ALU
 (almeno) una unità di controllo che interpreta e decodifica le istruzioni e le trasferisce alle altre CPU
componenti (capacità di controllo) →CU

 (almeno) una memoria per conservare i dati e le istruzioni stesse La memoria è organizzata logicamente
come una lista di LOCAZIONI DI
(capacità di immagazzinare informazioni)
MEMORIA (o celle di memoria).
- L’alba
• Volendo ripercorrere le idee che hanno portato fino ad immaginare e poi progettare macchine da calcolo dovremmo
andare molto dietro nel tempo. Tuttavia, quello che ci interessa davvero è la storia del «calcolatore elettronico digitale»,
che ha rivoluzionato la tecnologia del XX secolo, caratterizzando un'epoca.
• Non ci si sarebbe arrivati senza lo studio e i tentativi di alcune personalità notevoli, che precorrendo i tempi avevano
cominciato a progettare e costruire macchine calcolatrici già nei secoli precedenti.
•Tra questi, scegliamo di citare Blaise Pascal (1623-1662, francese), che nella Francia della metà del XVII secolo
progettò, costruì e vendette la prima macchina calcolatrice funzionante, interamente meccanica (azionata a manovella), in
grado di compiere egregiamente somme e sottrazioni.
•La sua macchina fu ripresa ed ampliata da Leibniz (1646-1716, tedesco) in una che potesse eseguire anche
moltiplicazioni e divisioni.
• Leibniz espresse chiaramente l'opportunità di far compiere ad una macchina calcoli che comportavano solo una noiosa
perdita di tempo per gli studiosi.
• Questo tema fu mantenuto e portato avanti anche nell'opera di un'altra grande personalità quale l'inglese Charles
Babbage (1792-1871) che progettò dettagliatamente la Macchina Analitica (Analytical Engine).
• A lui si deve probabilmente anche il primo accordo tra uno scienziato ed un governo: egli riuscì ad ottenere supporto
economico per il proprio progetto in Inghilterra, ma per il susseguirsi di difficoltà impreviste e per l'inadeguatezza dei
tempi, la macchina non fu mai realizzata.
• Il suo progetto però prevedeva un'unità aritmetica, la capacità di realizzare salti condizionati e cicli, e una memoria
integrata.
• Sarebbe inoltre stata programmabile: Ada Lovelace scrisse per questa macchina un programma in grado di calcolare i
numeri di Bernoulli.
• L'insieme dei principi alla base della macchina di Babbage è a tutti gli effetti vicinissimo a quello che ha ispirato
successivamente il progetto dei veri e propri calcolatori funzionanti.
• La tecnologia divenne matura per l'interesse verso i calcolatori,
sia in Europa che negli Stati Uniti, solo dopo l'inizio del XX Interessante è la visita al sito web del National
secolo. Museum of Computing a Bletchley Park,
• Già nei primi anni 40 l'americano John Atanasoff (1903-1995) anche nota come Stazione X, ovvero una
scriveva del progetto di una macchina elettronica ad aritmetica tenuta situata a nord ovest di Londra.
binaria per la risoluzione di un sistema di equazioni lineari, ma Durante la Seconda Guerra Mondiale,
le sue idee non ebbero la fortuna meritata a causa Bletchley Park fu il sito dell'unità principale di
dell'inadeguatezza della tecnologia del suo tempo. crittoanalisi del Regno Unito, nonché sede
• Il vero stimolo per lo sviluppo che portò ai calcolatori della Scuola governativa di codici e cifrazione.
elettronici venne dalla Seconda Guerra Mondiale: primi tra tutti, In questo museo c’è un’intera galleria dedicata
gli inglesi si impegnarono nella costruzione del segretissimo a COLOSSUS e altre esposizioni riguardo la
computer COLOSSUS (1943) per interpretare i messaggi rottura di ENIGMA.
tedeschi cifrati da ENIGMA, con anche il contributo (1912-
1954) del grande matematico Alan Turing.

LA MACCHINA DI TURING
• Le caratteristiche teoriche generali di una macchina in grado di eseguire procedure logiche e matematiche in modo
automatico sono state definite proprio da Turing nel 1937. La sua intenzione era di formalizzare il concetto di algoritmo
fino ad individuarne i limiti nell’applicazione.
• Turing ideò una macchina teorica in grado di simulare il comportamento di un uomo intento a eseguire un calcolo
aritmetico.
• La macchina di Turing ha una precisa struttura logica, funziona eseguendo una successione di passi discreti e il suo
comportamento è determinato da un insieme finito di regole: specificando in modo opportuno le regole, una macchina di
Turing può eseguire calcoli di qualsiasi natura e complessità.
• Egli dimostrò poi che è possibile progettare una macchina UNIVERSALE, in grado cioè di imitare qualsiasi altra
macchina di Turing, attraverso un processo di codifica che assomiglia molto al nostro moderno concetto di programma.
Dimostrò anche che la sua macchina universale poteva risolvere qualsiasi problema a patto che esso fosse
RISOLVIBILE, ovvero che esistesse un algoritmo per la sua soluzione.
• Anni di studi di informatica teorica che ritrovavano sempre le conclusioni di Turing fanno oggi valere la famosa Tesi di
Church: «L’insieme dei problemi effettivamente risolvibili con qualsivoglia metodo meccanico coincide con quello dei
problemi risolvibili dalla macchina di Turing.»
• Sebbene nemmeno concepita per essere realizzata, la macchina di Turing è stata ispirazione per le progettazioni
successive.

In memoria di Alan Turing è stato istituito nel 1966 dalla ACM (Association for Computing Machinery) l’A.M.
Turing Award (Premio Turing). Considerato da molti il «premio Nobel dell’informatica», viene assegnato ogni
anno a una personalità che eccelle per i contributi di natura tecnica offerti alla comunità informatica.

• Il primo vero computer di uso generale realizzato e funzionante, si deve però ad Howard Aiken e al suo gruppo di lavoro
della Harvard University: il Mark I (progetto iniziato nel 1939 e terminato nel 1943).
• Era un dispositivo digitale elettromeccanico, basato su relè (interruttori azionati da un elettromagnete), composto da 72
parole di 23 cifre decimali, con un tempo di istruzione di 6 secondi e un nastro di carta per l'input e l'output.
• Questo calcolatore rimase a disposizione della Marina Militare degli Stati Uniti per tutta la Seconda Guerra Mondiale ed
ebbe un alto impatto mediatico, permettendo la nascita e lo sviluppo del laboratorio universitario di Harvard.
• Il Mark I e i suoi successori ebbero un breve successo, presto messi a confronto con i calcolatori elettronici che
sfruttavano valvole termoioniche.

- Generazione I- Calcolatori a valvole (parte 1)


• Durante la guerra, negli Stati Uniti l'esercito stabilì di finanziare la costruzione dell'ENIAC (Electronic Numerical
Integrator And Computer) da parte di John Mauchley, che aveva studiato anche il lavoro di Atanasoff.
• L'ENIAC era costituito da 18000 valvole termoioniche-componenti in grado di funzionare come interruttori elettronici
comandati da segnali elettrici, cioè triodi e 1500 relè-pesava 30 tonnellate e consumava 140 KW di energia. Era dotata di
20 registri, ciascuno in grado di memorizzare un numero decimale a 10 cifre. Veniva programmato regolando 6000
interruttori multi-posizione e connettendo una moltitudine di prese con una vera e propria foresta di cavi.
• Non fu usato per scopi bellici perché terminato troppo tardi, ma, presentato a una scuola estiva, scatenò l'interesse
generale verso la costruzione di grandi computer digitali.
• Nel 1944 John von Neumann (1903-1957), geniale scienziato paragonato a Leonardo da Vinci per le sue abilità, che era
già allora uno dei più importanti matematici al mondo, fu invitato a vedere l'ENIAC.
• Goldstine racconta che Eckert, scienziato partecipante al progetto dell'ENIAC, sapendo dell'imminente visita di Von
Neumann, preannunciò che avrebbe capito se costui fosse un genio come si diceva o meno dalla prima domanda che
avrebbe fatto: la prima domanda di Von Neumann fu riguardo la struttura logica della macchina, e questo bastò ad Eckert
per stabilire che si trattava davvero di un genio.
• In seguito Von Neumann collaborò poi all'evoluzione del progetto in EDVAC (Electronic Discrete Variable Automatic
Computer) all'università della Pennsylvania.
• Quando il progetto dell'EDVAC si fermò, Von Neumann ne sviluppò, con il collaboratore Goldstine (1913-2004), la
propria versione a Princeton: la macchina IAS (1952), che ha costituito la base per tutti i computer digitali a venire.
• Le idee innovative introdotte erano la rappresentazione dei programmi, come i dati, in forma numerica all'interno della
memoria del computer, e la sostituzione dell'aritmetica decimale con una binaria, riprendendo il funzionamento della
macchina di Atanasoff: l’IAS è stata la prima macchina con programma memorizzato.
• Il progetto che Von Neumann descrisse è rimasto noto come macchina di Von Neumann.
LEZIONE 2: STORIA DEI SISTEMI DI CALCOLO
- Generazione I- Calcolatori a valvole (parte 2)
• Una valvola termoionica (o tubo a vuoto) è un triodo che funziona da interruttore.
• Con un’opportuna tensione sulla griglia è possibile attivare la corrente elettrica tra catodo e anodo.
• Costruttivamente assomiglia a una lampadina.
• L’IAS fu in grado di eseguire le prime operazioni nell'estate del 1951 e divenne completamente operativo nel 1952.
• Prototipi sperimentali in grado di memorizzare istruzioni esistevano già da pochissimi anni ma questa è stata la prima
macchina del genere davvero operativa e davvero utilizzata.
• Prima di questa possibilità che oggi ci sembra ovvia, ogni volta che si voleva usare un nuovo programma, andavano
riconfigurati i circuiti della macchina: per farlo con il calcolatore ENIAC ci volevano diversi giorni.
• Da questo momento invece, si scrivono (letteralmente) le istruzioni con un mezzo di input semplice (come la tastiera) e
relativamente veloce e queste vengono memorizzate per la durata dell’esecuzione insieme ai dati sui cui devono agire.
• In quel momento le macchine calcolatrici concrete diventavano facilmente programmabili, e ne veniva aperto l'utilizzo
ad infinite possibilità (in pratica nasceva il concetto di calcolatore così come ancora oggi viene inteso).
• Il primo calcolatore commerciale a valvole termoioniche fu l'UNIVAC, prodotto dalla compagnia fondata da Mauchley
ed utilizzato nel 1952 per i primi exit-poll delle elezioni presidenziali statunitensi: anticipò correttamente la vincita di
Eisenhower (se l’ENIAC occupava una stanza di 9x30 mt e pesava più di 30 tonnellate, l’UNIVAC pesava SOLO 5
tonnellate, mentre l’unità centrale era lunga SOLO più di 5 metri e alta SOLO 2 metri e mezzo).
• Tra le ultime macchine a valvole ricordiamo invece quelle che seguivano il modello 709 dell'IBM (1958), società nata
per il commercio di schede perforate che da pochi anni si interessava ai computer veri e propri.
SCHEDA PERFORATA
• Sono state costruite apparecchiature elettromeccaniche per forare, ordinare, intabellare e stampare le schede. Queste
macchine permettevano di compiere sofisticati compiti di elaborazione dati molto tempo prima dell'invenzione dei
calcolatori elettronici.
• Una scheda perforata è un pezzo di cartoncino leggero viene suddiviso in molteplici porzioni che possono essere
attraversate da un foro o lasciate intatte. I pezzetti di carta rettangolare che vengono asportati durante la perforazione
vengono chiamati chad.
• Ogni singola posizione sulla scheda rappresenta una singola cifra binaria (bit).
• Il formato della scheda perforata IBM, che in seguito è divenuto lo standard, prevede 80 colonne con 12 posizioni di
perforatura ciascuna, per rappresentare 80 caratteri la loro dimensione fu standardizzata esattamente a 187,325 x 82,55
mm, con uno degli angoli superiori tagliato in diagonale.
• La principale ragione dell'angolo tagliato era evitare che la scheda potesse essere inserita al contrario. Se la scheda
veniva inserita nel lettore in modo errato andava a colpire una levetta. Questa attivava un microinterruttore e fermava la
macchina finché la scheda non venisse inserita correttamente come previsto dal sistema.
• Una sequenza ordinata di schede che siano da dare in input a o ricevute in output dalla stessa applicazione, si dice deck.
• I dati venivano «scritti» sulla scheda tramite la perforatrice, che era una macchina per scrivere grande e rumorosa.
Spesso il testo veniva stampato da un’altra macchina (interprete) nella parte superiore della scheda, permettendo di
leggerla più facilmente. Modelli più evoluti di perforatrici permettevano di eseguire entrambe le operazioni
contemporaneamente.
• Le schede verificate venivano marcate con una tacca rotonda sul lato destro. Le schede errate venivano sostituite
dall'operatore alla perforatrice. C'era una grossa richiesta di operatori alla perforatrice, normalmente donne, che
lavoravano full-time alla perforatrice o al controllore.

- Generazione II - Calcolatori a transistor


• Nel 1948 i Bell Labs inventarono il transistor, un componente elettronico a stato solido realizzato con un cristallo di
germanio che poteva essere utilizzato come interruttore elettronico comandato da segnali elettrici e quindi poteva
sostituire la valvola termoionica: questa invenzione valse il premio Nobel per la fisica nel 1956 ai ricercatori coinvolti.
• Il transistor rivoluzionò i computer al punto che nei tardi anni '50 resero obsolete le valvole.

Il transistor è un componente elettronico a stato solido realizzato con un cristallo di germanio,


che può essere utilizzato come interruttore automatico (ON/OFF): una corrente elettrica
inviata nella base (B) controlla la corrente che scorre tra l’emettitore (E) ed il collettore (C).
Variando la tensione elettrica, il transistor può rappresentare l’1 e lo 0, necessari al
funzionamento del calcolatore elettronico. Sono molto più piccoli e da subito 100 volte più
veloci delle valvole termoioniche.

• Nel 1954 il germanio viene sostituito con un altro semiconduttore, il silicio, molto più diffuso ed economico.
• La memoria negli anni 60 era costituita da nuclei di ferrite.
• Il primo (super)calcolatore a transistor fu costruito presso i Lincoln Laboratory del M.I.T., nel 1956 e fu chiamato TX-0
(Transistorized eXperimental computer 0).
• Seguì il più evoluto TX-2, precursore della macchina messa in commercio solo diversi anni dopo (1961) dalla nascente
Digital Equipment Corporation (DEC), la PDP-1 (Programmed Data Processor 1), osteggiata dagli stessi finanziatori che
non credevano potesse esserci mercato per i computer.
• il DEC PDP-1 (1960) è stato il primo calcolatore commerciale a transistor, nonché il primo con monitor e tastiera.
• Intanto IBM nel 1959 costruiva un calcolatore a transistor sul modello 709, l'IBM 7090, con prestazioni doppie rispetto
al PDP-1, ma che costava diversi milioni di dollari, contro i 120000 dell'altra.
• tra i progettisti del prototipo dell'IBM 7090 c'era il giovane promettente Ph.D. Michael J. Flynn;
• questa macchina fu venduta all’Aeronautica Militare degli Stati Uniti, che vi calcolava le traiettorie di volo dei
missili Saturno della NASA.
• Furono vendute decine di PDP negli anni 60.
• Il PDP-1, di cui fu fornito anche il M.I.T, aveva uno schermo e la capacità di disegnare punti in qualsiasi zona di questo
schermo: è stato il primo computer con monitor e tastiera. Gli studenti del M.I.T. lo programmarono per giocare a
spacewar di fatto inventando il primo videogioco della storia.
• L'IBM, che pure con la 7094 (macchina ad aritmetica binaria parallela su registri a 36 bit) si imponeva sul mercato,
cominciò a fare veri profitti vendendo quasi contemporaneamente una piccola macchina per le aziende, chiamata 1401
(aveva una «sorella» pensata per gli scienziati, modello 1620), in grado di leggere e scrivere nastri magnetici, leggere e
perforare schede e stampare output alla stessa velocità del 7094 ma ad una frazione del prezzo.

- Supercalcolatori
• Nel 1964 una sconosciuta società, la Control Data Corporation (CDC) produsse il modello 6600 (CDC 6600), disegnato
da Seymour Cray (1925-1996, figura rimasta leggendaria come Von Neumann), con prestazioni di un ordine di grandezza
maggiori del 7094, grazie all'alto parallelismo e fu subito amato dai matematici numerici.
• Era una macchina dotata di diverse unità funzionali che potevano lavorare contemporaneamente e necessitava di
un'attenta programmazione.
• Inoltre, la CPU veniva dedicata interamente ai calcoli veri e propri, mentre tutti gli altri dettagli di gestione del
programma e dell'input/output venivano affidati a CPU secondarie.
• In pratica, questa macchina conteneva idee chiave per i calcolatori prodotti decine di anni dopo ed è stato il primo
supercalcolatore così chiamato.

- Generazione III - Circuiti integrati o Chip


• Con la miniaturizzazione dei componenti elettronici, venne l'idea di combinare diversi componenti (transistor, diodi,
resistenze, ecc.) su una piastrina di semiconduttore di dimensioni più piccole di un francobollo: era il 1958 e Robert
Noyce inventava il circuito integrato. I computer potevano essere più piccoli, più veloci e più economici.
• IBM, ormai leader nel mondo dei computer, introduce nel 1964 il System/360, basato su circuiti integrati e pensato sia
per i calcoli scientifici sia per quelli commerciali: da questo progetto produce una famiglia di computer tutti dotati dello
stesso linguaggio assemblativo ma di dimensione e potenza diverse.
• Questo colmava la distanza che c'era tra le sue due produzioni precedenti (7094 e 1401) e permetteva di creare software
che avrebbe funzionato su tutte le macchine della famiglia (a meno di problemi di quantità di memoria), semplificando il
lavoro e gli investimenti dei clienti e creando una tendenza poi seguita da molti altri produttori.
• Il 360 era multiprogrammabile (poteva contenere più programmi in memoria) e poteva anche emulare altri computer,
in particolare i modelli precedenti di IBM, realizzando la retrocompatibilità che ne velocizzò la diffusione. Aveva registri
a 32 bit per l'aritmetica binaria ma anche una memoria orientata al byte, molto grande (2^24 byte) per un'epoca in cui
ogni byte costava alcuni dollari.
• Dopo questa l'IBM produsse diverse macchine compatibili, ma quando si trattò di indirizzare una memoria di 2^32 byte
fu costretta a fare sostanziali cambiamenti per introdurre il nuovo tipo di indirizzamento.
• Nel 1965 intanto DEC con il PDP-8 (considerato il
primo minicomputer per la piccola dimensione Il PDP-10 è, alla fine degli anni 60, il primo computer
relativamente ai suoi contemporanei) introdusse il incontrato da Bill Gates. La scuola aveva affittato un certo
bus unico di connessione, e di questa macchina numero di ore di utilizzo con lo scopo di scoprire e
vendette decine di migliaia di esemplari. correggere i bug. Gates, il compagno di studi Paul Allen e
altri studenti (alcuni dei quali diverranno poi dipendenti di
• il DEC PDP-11 era una sorta di versione piccola Microsoft), divennero inseparabili dal computer…
dell'IBM 360, e anch'esso ebbe la sua famiglia e il Creando anche non pochi problemi!
suo enorme successo soprattutto nelle università.

- Legge di Moore (1965)


• L'aumento delle prestazioni è anche la principale chiave per l'interpretazione della crescita tecnologica dei sistemi di
calcolo.
• Gordon Moore (1929-vivente), cofondatore della Intel, nel 1965, su base del tutto empirica, fece una predizione,
leggermente modificata da lui stesso dieci anni dopo, secondo cui: La complessità dei componenti a costo minimo
raddoppierà all'incirca ogni due anni.
• Qualche tempo dopo un altro ingegnere della Intel, David House, reinterpretava questa osservazione/previsione nel
modo in cui è oggi ben nota: La potenza di calcolo dei microprocessori raddoppierà ogni 18 mesi.
• Tale legge ha trovato riscontro nella pratica per oltre 50 anni, anzi, si può dire che ha instaurato un ciclo virtuoso,
spingendo gli avanzamenti tecnologici verso prodotti migliori e più economici, che a loro volta spingono la creazione di
nuove applicazioni, che di nuovo incentivano l'avanzamento tecnologico, e così via.

- Generazione III – VLSI


• Nel 1971 la Intel crea il primo microprocessore, realizzato interamente su un singolo Chip: Intel 4004.
• Fra i padri del microprocessore c’è l’italiano Federico Faggin che è responsabile della sua progettazione.
• Gli elementi del 4004 erano:
-16 registri
-ALU CURIOSITÀ

-CU Nel 68 Ray Holt progetta il vero primo


microprocessore, più potente del 4004, ma per
-Decodificatore di istruzioni
la Marina Militare Americana, e il progetto è
-Generatore dei segnali di temporizzazione stato declassificato solo nel ’99. Dunque, dopo
-Controllo del bus per le funzioni di I/O 30 anni Holt ha potuto finalmente rivendicare il
suo ruolo di «primo arrivato».
• …era praticamente una Macchina di Von Neumann monolitica e molto molto piccola.

• Tecnologia detta VLSI (Very Large Scale Integration) perché con l’avvicinarsi degli anni ‘80 si inserivano sullo stesso
chip sempre più transistor, da migliaia a milioni. E i computer diventarono sempre più piccoli e più veloci. Nelle
università si poteva fornire di computer ogni dipartimento, e con il crollo dei prezzi, anche i privati potevano
permettersene uno: nascevano i personal computer, destinati ad usi nuovi, come l'elaborazione di testi, l'amministrazione
domestica o videogiochi, e venduti in scatole di montaggio, senza software.
• Nel 1973 Gary Kildall (1942-1994) aveva scritto il sistema operativo CP/M, scritto per il processore Intel 8080, i cui
concetti fondamentali sarebbero stati la base per MS-DOS.
• A Albuquerque Bill Gates (1955 – vivente) e Paul Allen (1953 – 2018) il 4 aprile 1975 diedero vita a Microsoft, creata
dopo che Gates – forse un po’ spinto da Allen, più interessato all’informatica di lui – abbandonò gli studi presso
l'Università di Harvard (in legge).
 è una società concentrata sul SOFTWARE (sistemi operativi in particolare) ma inizia una fortunata
collaborazione con la società produttrice di hardware IBM agli inizi degli anni 80 (durata fino al ‘91).
• Siamo nel 1976 quando Steve Wozniak (1950-vivente) progetta l'Apple, e riesce ad ottimizzarlo ma soprattutto a
commercializzalo grazie al suo amico ed ex compagno di studi Steve Jobs (1955-2011).
• Il 1º aprile 1976 i due fondarono, insieme all'amico Ronald Wayne, la società Apple Computer
 vendendo il furgoncino Volkswagen di Jobs e la calcolatrice HP di Wozniak, misero insieme alcune migliaia di
dollari con cui acquistarono i componenti necessari a iniziare la produzione.

• Paul Terrell, che aveva da poco aperto The Byte Shop, la prima catena di negozi dedicati ai computer, fu molto
impressionato dalla macchina e propose a Jobs l'acquisto di 50 computer già assemblati e pronti all'uso per 500 $
cadauno, da consegnare in 30 giorni.
• Jobs accettò, ben sapendo che il costo dei componenti necessari a realizzare tutti quei computer era molto al di là delle
loro possibilità.
• Nonostante ciò, riuscì a convincere un fornitore di componenti ad accettare un pagamento a 30 giorni senza interessi.
• Con i componenti disponibili, i computer furono assemblati da Wozniak presso la sua postazione di lavoro alla
Hewlett-Packard e poi testati e immagazzinati prima della vendita nel garage dei genitori di Steve Jobs.

APPLE 1
• L'Apple I è semplicemente una scheda madre completamente assemblata.
• Per ottenere un computer funzionante bisogna aggiungervi un paio di alimentatori in grado di fornirle le tensioni
elettriche richieste, una tastiera e collegarlo ad uno schermo (un televisore), che andavano acquistati a parte da altri
fornitori.
• È per questo motivo che molti Apple I vennero assemblati in case di legno: non essendoci all'epoca un mercato di case,
molti utenti se lo costruirono da soli e spesso utilizzavano il legno.
• Wozniak era l'unica persona che poteva offrire assistenza per quella macchina, avendola progettata e costruita
personalmente.

• Seguì nel 1977 l'Apple II (il primo calcolatore della Apple a grande diffusione), che aggiungeva al testo scritto anche
grafica e colori, veniva venduto già assemblato e con il sistema operativo AppleDOS.
• Questo personal computer ebbe grande diffusione tra privati e scuole, e, con la forza della loro semplicità di utilizzo,
resero immediatamente la Apple (società fondata per l'occasione) un pericoloso concorrente per le altre compagnie.
• Intel cominciò a distribuire il processore Intel 8080 con il CP/M su floppy disk, con tanto di file system e interprete di
comandi scritti da tastiera (shell).
• Ma dopo il successo ottenuto dalla Apple, anche l'IBM si diede ai personal computer.
• Nel 1981, IBM introdusse sul mercato, con tanto di libro degli schemi e dei diagrammi dei circuiti, il suo PC IBM, con
sistema operativo Microsoft MS DOS, che divenne subito il computer più venduto (e più clonato) della storia (IBM PC
5150).
• Microsoft aveva comprato (per soli 100000 dollari) da altra società una prima versione del DOS che aveva poi fatto
modificare allo stesso creatore, che non aveva un contratto esclusivo con la società di origine, per adattarlo al 5150.
•IBM però non vuole comprare la licenza (i diritti restano Microsoft), e si accordano per la fornitura dei sistemi operativi.
• Intanto Apple produceva prima l'Apple Lisa, per la prima volta dotato di interfaccia grafica.

LISA
• Il nome è in onore della figlia di Jobs, a cui fu collegato il poco significativo acronimo Local Integrated System
Architecture.
• L'interfaccia grafica del Lisa nacque da un accordo con la Xerox: lo Xerox Alto fu il primo computer con una
interfaccia grafica, che introduceva la metafora della scrivania (Desktop) e il mouse. Tutte le sue novità vennero
perfezionate e riversate nel Lisa.
• Il Lisa fu il primo computer dotato di interfaccia grafica (GUI) ad entrare nelle case della gente comune.
• Il Lisa era dotato di processore Motorola 68000, di 1 MB di RAM e di 2 dischi floppy da 5,25 pollici, in grado di
memorizzare fino a 871 kB.

• …e poi nel 1984 il più fortunato, Macintosh a cui Microsoft fornisce il pacchetto Office.
• La Microsoft di Bill Gates cominciò a sviluppare, seguendo le idee della Apple l'interfaccia grafica per MS-DOS
chiamata Windows che divenne poi un vero e proprio sistema operativo evolutosi negli anni.
 Windows 1.0 viene messo sul mercato nell’ 85, ma ha scarso successo e non fornisce un sistema
operativo completo, è solo un’estensione di MS-DOS, con molti limiti.
 Con Windows 2.0 nell’ 87 inizia una prima rudimentale distribuzione del pacchetto Office (Word ed
Excel).
 Con Windows 3.0 inizia la fortuna del sistema, e nasce l’ormai famosissimo logo.
• In questo modo la concorrenza di IBM e Microsoft alla Apple era spietata, nonostante non potessero competere in
termini tecnologici, perché i loro prodotti risultavano più economici.
• Il Macintosh sopravvisse a stento a questa guerra, e la società si è ripresa davvero soltanto a metà degli anni 90.
• Del 1981 è anche la comparsa del primo (?) calcolatore portatile, Osborne-1 della Osborne Computer Corporation,
società che fallì poco dopo, incapace di battere la concorrenza.
• Intel realizzò diversi processori sull'onda della valida architettura 8080, di cui ebbe particolare fortuna l’80386 (1985),
con tutti i suoi figli, compresi i Pentium (1993, Pentium II nel 1997, Pentium III nel 1999).
• Nel 1989 Tim Berners-Lee propone il progetto World Wide Web al CERN.
• Microsoft dagli anni ‘90 prosegue i propri progetti affiancando le produzioni Intel, di fatto detronizzando IBM.
• Nel 1992 DEC presentò Alpha, una macchina RISC a 64 bit, dalle prestazioni nettamente superiori a tutti i precedenti,
ma le macchine a 64 bit hanno cominciato a diffondersi solo molto dopo.

LEZIONE 3: RAPPRESENTARE I DATI


- Tipo di dato
• Abbiamo detto che in un calcolatore moderno i DATI (e le
istruzioni) sono conservati nella memoria. Ma come?
• I dati sono classificati secondo dei TIPI.
• Un TIPO DI DATO 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 dati elementari sono:
 Il tipo intero
 Il tipo alfanumerico
 Il tipo logico
 Il tipo reale
• Tipi di dati complessi si possono costruire a partire da
quelli elementari.

- Tipo di dato: INTERO


• Il tipo intero indica il sottoinsieme dei numeri relativi (quindi interi positivi e negativi) che possono essere rappresentati
nella memoria di un calcolatore.
• Poiché le locazioni di memoria sono costituiti da bit, i dati di tipo intero sono rappresentati col sistema binario (base
b=2).
• Nella rappresentazione posizionale, le cifre di un numero sono i coefficienti di una combinazione lineare delle potenze
della base.

ESEMPIO
Il numero intero K=18 (in base b=10) può essere rappresentato in base b=2 come K=10010
10010 = 0*2^0 + 1*2^1 + 0*2^2 + 0*2^3 + 1*2^4= 0+2+0+0+16 = 18

• In una locazione di memoria si rappresentano le cifre binare della


rappresentazione del numero intero con la convenzione che il primo
bit rappresenta il segno: ad esempio 1 = - e 0 = +.
• La limitatezza di una locazione di memoria implica un Massimo e un
Minimo numero intero rappresentabili.
• Con una sola locazione di memoria da 8 bit è possibile rappresentare
un insieme molto limitato di numeri interi (da -127 a 127).
• Comunemente nei calcolatori si usano parole da 4 locazioni (32 bit),
quindi
 Massimo intero rappresentabile è MAX = 231 − 1
 Minimo intero rappresentabile è -MAX = −(231− 1)
• In generale, se L è la lunghezza della parola,
𝑀𝐴𝑋 = 2𝐿−1 − 1
−𝑀𝐴𝑋 = −(2 𝐿−1 − 1)
• Un numero intero K è rappresentabile se è compreso tra MAX e –MAX, ovvero
–MAX ≤ K ≤ MAX
• Sul tipo di dati intero sono definite le tradizionali operazioni aritmetiche
 Addizione
 Sottrazione
 Moltiplicazione
 Divisione
• Poiché nella rappresentazione del tipo intero non è previsto il punto decimale (o non sarebbero più INTERI), la
divisione tra numeri interi produce sempre un numero intero per troncamento.
 Esempio: se A= 5, B= 2 allora A/B=2
• ATTENZIONE: Alcune proprietà dell’aritmetica tradizionale non valgono in aritmetica finita.

ESEMPIO
Se MAX=127, quanto fa 60+70?
-127<60<127 quindi 60 è rappresentabile,
-127<70<127 quindi 70 è rappresentabile,
60+70=130>127 non è rappresentabile!!
Se MAX=127, quanto fa 60+70-40?
-127<40<127 quindi anche 40 è rappresentabile
(60+70) –40 non è rappresentabile, ma
60 + (70-40) è rappresentabile

• La situazione per cui il risultato di una operazione tra due numeri rappresentabili non è rappresentabile è detta
OVERFLOW.

ESEMPIO
Se la base è b=2, e la parola è lunga L=32 (situazione reale!), allora il massimo rappresentabile è: 𝑀𝐴𝑋=2𝐿−1−1≅109
Se K=13 e ne calcoliamo il FATTORIALE: K! = 6227020800 >𝑀𝐴𝑋x
Quindi 13! è una operazione che provoca overflow.

- Tipo di dato: ALFANUMERICO


• Il tipo di dati alfanumerico indica l’insieme finito di caratteri solitamente usato nel linguaggio naturale scritto:
 Lettere dell’alfabeto (maiuscole e minuscole)
 Le cifre decimali (0, 1, 2, …, 9)
 I caratteri speciali e di punteggiatura (!, @, #, $, [, {, +, -, …)
• I caratteri sono combinati tra loro in stringhe
• Il tipo di dato alfanumerico è rappresentato mediante opportuni codici
• Codice: funzione di trasformazione di un carattere in un insieme di bit
• Esistono vari tipi di codici, dal 1968 è standard il codice ASCII
• American Standard Code for Information Interchange
• codice a 7 bit + 1 di controllo
• Si concatenano caratteri per formare STRINGHE.
• Esempio: la parola NAPOLI si rappresenta con una stringa di 6 caratteri.
• Sul tipo di dato Alfanumerico sono definite le operazioni di
 Confronto, secondo l’ordinamento alfabetico, conservato dal codice ASCII
 Esempio: A<D<V
 Concatenazione
 Esempio: pesce//cane = pescecane
Ovviamente sul sottoinsieme del tipo alfanumerico {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} non sono definite le operazioni aritmetiche.

- Tipo di dato: LOGICO


• Il tipo di dato Logico indica l’insieme costituito da due soli
elementi: {vero; falso}
• Si utilizza quindi nella verifica della veridicità di una
proposizione.

ESEMPIO
Proposizione P: «Napoli è in Campania»
• Per rappresentare i due valori in memoria sarebbe sufficiente un solo bit MA poiché la minima quantità di memoria
indirizzabile è la locazione di memoria il tipo di dato logico è rappresentato utilizzando un’intera locazione.

Sul tipo di dato logico si possono eseguire le operazioni di:

• Negazione: agisce su un solo dato logico e ne cambia il valore, se è vero diventa


falso, se è falso diventa vero.
 Esempio:
(3<5) = VERO, not (3<5) = FALSO; (A>C) = FALSO, not (A>C) = VERO
• Congiunzione: agisce su due dati logici, e dà risultato VERO solo se entrambi i
dati sono veri.
 Esempio:
(3>2) and (1<2) = VERO; (3>2) and (1>2) = FALSO
• Disgiunzione: agisce su due dati logici, ed è vera se almeno uno dei dati è vero.
 Esempio:
(3>2) or (1<2) = VERO; (3>2) or (1>2) = VERO; (3<2) or (1>2) = FALSO

- Tipo di dato: REALE


• Principale tipo di dato per il calcolo scientifico
• Utilizzato per rappresentare numeri decimali
• Basato sulla NOTAZIONE SCIENTIFICA NORMALIZZATA perché la struttura sia sempre la stessa
 Fissata una base intera 𝑏>1, un numero reale 𝑥 si scrive come 𝑥=𝑓∗𝑏𝑒
 𝑓∈ℝ è un numero minore di 1 (parte intera nulla) e la prima cifra decimale è sempre maggiore di 0
 La parte decimale (dopo il punto) si chiama mantissa di 𝑥
Qualsiasi numero
 𝑒∈ℤ si chiama esponente di 𝑥
reale si può scrivere in
 Se 𝑏=10, 35.267 = 0.35267 · 10^2
questa forma
 Se 𝑏=10, 0.00523 = 0.523 · 10^ (-2)
• Si chiama rappresentazione FLOATING POINT (virgola mobile)
 È il punto decimale che si sposta
• Per rappresentarlo in un sistema con base fissata, occorre memorizzare
mantissa ed esponente (con i relativi segni).

• Se b = 2, L = 8:
 2 bit per i
due segni,
4 per la
mantissa, 2
per

l’esponente
 Proviamo a rappresentare x = 6.5
 Binario: x = 110.1
 Floating point: x= +0.1101 · 2^11
 Proviamo a rappresentare y = -0.21875
 Binario: y = -0.00111
 Floating point: y= -0.1110 · 2^ (-10)
 Proviamo a rappresentare z = 5.75
 Binario: z = 101.11
 Floating point: z= +0.10111 · 2^11
 Proviamo a rappresentare w = 9.0
 Binario: w = 1001.0
 Floating point: w= 0.1101 · 2^100
Anche la rappresentabilità di un dato di tipo reale dipende dalla lunghezza della parola!
Non tutti i numeri sono rappresentabili!
• 2 vincoli
 PRECISIONE FINITA: sul numero di cifre della mantissa
o Il numero di cifre a disposizione per la mantissa t si chiama precisione del sistema aritmetico
o Tutti i numeri reali che hanno più di t cifre non possono essere rappresentati esattamente
 RANGE LIMITATO: sul numero di cifre dell’esponente
o Se q il numero di cifre a disposizione per le cifre dell’esponente, abbiamo
o 𝐸𝑚𝑖𝑛 = −(𝑏𝑞−1 − 1) è il minimo esponente rappresentabile
o 𝐸𝑚𝑎𝑥 = 𝑏𝑞−1 − 1 è il massimo esponente rappresentabile
o Gli esponenti al di fuori del range [𝐸𝑚𝑖𝑛, 𝐸𝑚𝑎𝑥] non possono essere rappresentati esattamente.
• ESEMPI
 Sistema aritmetico 1: b=10, t= 3, 𝐸𝑚𝑖𝑛= -5, 𝐸𝑚𝑎𝑥=5
 Il massimo numero reale POSITIVO rappresentabile è R=0.999 · 10^5
 Il minimo numero reale POSITIVO rappresentabile è R=0.100 · 10^ (-5)
 Sistema aritmetico 2: b=10, t= 5, 𝐸𝑚𝑖𝑛= -10, 𝐸𝑚𝑎𝑥=10
 Il massimo numero reale POSITIVO rappresentabile è R= 0.99999 · 10^10
 Il minimo numero reale POSITIVO rappresentabile è R= 0.10000 · 10^ (-10)
• L’insieme finito dei numeri reali esattamente rappresentabili su una macchina con un dato sistema aritmetico floating
point a precisione finita è detto: insieme dei numeri macchina.
• Nel 1989 viene definito lo standard IEEE 754 che rappresenta il formato di rappresentazione f.p. più diffuso.
• Disponibile in singola (32 bit), doppia (64 bit) e quadrupla (128 bit) precisione.
• Permette anche la rappresentazione di situazioni eccezionali come infinito, forme indeterminate e i numeri
denormalizzati.
• Per la singola precisione (32 bit) il sistema è caratterizzato da:
 Base b=2
 Precisione t=23
 Esponente minimo 𝐸𝑚𝑖𝑛= -126
 Esponente massimo 𝐸𝑚𝑎𝑥=127
• Dunque, dato il numero reale 𝑥=𝑓∗𝑏𝑒, se non è un numero macchina vale almeno una delle seguenti
 𝑒 > 𝐸𝑚𝑎𝑥: OVERFLOW, rappresentazione impossibile
 𝑒 < 𝐸𝑚𝑖𝑛: UNDERFLOW, 𝑥 si rappresenta con 0
 la mantissa ha più di t cifre: 𝑥 si rappresenta con un numero vicino che sia un numero macchina
• Esempi: b=10, t= 3
 𝑥 = 0.1251 · 102 si rappresenta con 𝑓𝑙(𝑥) = 0.125 · 102
 𝑥 = 0.1259 · 102 si rappresenta con 𝑓𝑙(𝑥) = 0.126 · 102
 𝑓𝑙(𝑥) è la rappresentazione floating point di 𝑥, si ottiene per:
 Troncamento (si eliminano le cifre decimali
in eccesso)
• 𝑓𝑙 (0,1251 ∗ 102) = 0,125 ∗ 102
• 𝑓𝑙 (0,1259 ∗ 102) = 0,125 ∗ 102
 Arrotondamento (si approssima x con il
numero macchina più vicino)
• 𝑓𝑙 (0,1251 ∗ 102) = 0,125 ∗ 102
• 𝑓𝑙 (0,1259 ∗ 102) = 0,126 ∗ 102
• Sul tipo di dati reale sono definite le tradizionali operazioni:
 Addizione f.p.
 Sottrazione f.p.
 Moltiplicazione f.p.
 Divisione f.p.
• Analogamente al tipo di dato intero, il risultato è definito solo se gli operandi sono rappresentabili, e il risultato è
rappresentabile.
• ATTENZIONE: Alcune proprietà dell’aritmetica tradizionale non valgono in aritmetica floating point a precisione finita
(associativa, commutativa, distributiva…)!

- APPENDICE: i numeri e le basi


• Un numero è una sequenza finita di simboli detti cifre.
• I simboli utilizzati dipendono dal sistema di numerazione utilizzato.
• Il sistema di numerazione usualmente utilizzato è detto posizionale decimale
• posizionale indica che il valore di una cifra dipende dalla posizione che essa ha all’interno di un certo numero,
• decimale indica che la base utilizzata è b = 10. I simboli utilizzati in base 10 sono 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9.
• ESEMPIO: scrivendo 9102.917 in base 10 intendiamo esprimere il numero
9 × 103 + 1 × 102 + 0 × 101 + 2 × 100 + 9 × 10−1 + 1 × 10−2 + 7 × 10−3
•Si noti che la notazione posizionale non è l’unica esistente.
•Esistono anche altri sistemi di numerazione, ad esempio la numerazione romana, in cui ogni cifra del numero
rappresenta sempre il proprio valore (M = 1000, X = 10, V = 5, I = 1, . . .).
• Nulla vieta, per rappresentare un numero reale 𝛼 ∈ ℝ, di
utilizzare basi diverse dalla decimale.
• Sia 𝑏 ∈ ℕ una base qualsiasi. Per rappresentare i numeri in
base b sono necessari esattamente b simboli.
• Se 2 ≤ 𝑏 ≤ 10 si usano come simboli le prime b cifre della base
decimale, ovvero i simboli 0, 1, ..., b − 1.
• Se 𝑏 > 10, si aggiungono alle 10 cifre decimali le lettere
maiuscole dell’alfabeto.
•Quindi, generalizzando, un numero 𝛼 ∈ ℝ può essere espresso in base b nella forma
n

𝑎=± (𝑎𝑛𝑎𝑛-1𝑎𝑛-2…𝑎2𝑎1𝑎0 *𝑎−1𝑎−2𝑎−3…) 𝑏=± ∑ ai b ⅈ


i=−∞

• La parte che precede il punto di radice viene detta parte intera e quella che segue il punto di radice viene detta parte
frazionaria.
• Se lavoriamo con una base generica b, è importante indicare in quale base è espresso un numero dato, in quanto il suo
valore varia al variare di b.
• ESEMPI
123.110 = 1 × 102 + 2 × 101 + 3 × 100 + 1 × 10−1 = 123.110
123.17 = 1 × 72 + 2 × 71 + 3 × 70 + 1 × 7−1 = 66.142857142...10
123.14 = 1 × 42 + 2 × 41 + 3 × 40 + 1 × 4 – 1 = 27.251010
• Lo stesso numero necessita di un numero di cifre maggiore o uguale, al diminuire della base b.
• ESEMPIO
25310 = 𝐹𝐷16 = 3758 = 111111012
Come convertire un numero reale FINITO da una base 𝑏1 a una base 𝑏2.
Caso 𝒃𝟐 = 𝟏𝟎
Vi sono due possibili algoritmi per calcolare il valore decimale (che potrebbe non essere finito) di un numero reale
(finito) espresso in base qualsiasi 𝑏1:
1. Utilizzo della notazione posizionale: si calcola il valore utilizzando la definizione
n
𝑎=± (𝑎𝑛𝑎𝑛-1𝑎𝑛-2…𝑎2𝑎1𝑎0 *𝑎−1𝑎−2𝑎−3…) 𝑏=± ∑ ai b

i=−∞

• ESEMPI:
• 2401.23145 = 2×53 + 4×52 + 0×51 + 1×50 + 2×5−1 + 3×5−2 + 1×5−3 + 4×5−4 = 351.534410
• 110110.1012 = 1×25 + 1×24 + 0×23 + 1×22 + 1×21 + 0×20 + 1×2−1 + 0×2−2 + 1×2−3=54.62510
2. Utilizzo dell’Algoritmo di Horner: si considerano separatamente la parte intera e la parte frazionaria del numero e
poi si procede come segue:
•Parte intera: Partendo dalla prima cifra significativa alla sinistra, verso destra, si moltiplica il valore per la base
𝑏1e si aggiunge la cifra successiva. Il risultato si moltiplica per la base 𝑏1e si aggiunge la cifra successiva, e così
via sino all’esaurimento delle cifre. Ovvero:
(𝑎𝑛𝑎𝑛 − 1𝑎𝑛−2 … 𝑎2𝑎1𝑎0) 𝑏 = ((… ((𝑎𝑛 × 𝑏1 + 𝑎𝑛−1) × 𝑏1+𝑎𝑛−2) × 𝑏1+⋯) × 𝑏1 + 𝑎1) × 𝑏1 + 𝑎0
•Parte frazionaria: Partendo dalla prima cifra significativa alla destra della parte frazionaria, verso sinistra, fino al
punto di radice si divide il valore per la base 𝑏1e si aggiunge la cifra precedente.
•Il risultato si divide per la base 𝑏1e si aggiunge la cifra precedente e così via sino all’esaurimento delle cifre,
terminando con una divisione per 𝑏1. Ovvero:
(0. 𝑎−1𝑎−2𝑎−3…𝑎−𝑚+1𝑎−𝑚) 𝑏= ((… ((𝑎−𝑚: 𝑏1 + 𝑎−𝑚+1): 𝑏1+𝑎−𝑚+2): 𝑏1 + ⋯): 𝑏1 + 𝑎−1): 𝑏1
•ESEMPIO: 110110.1012 = 54.12510
parte intera ((((1×2+1) ×2+0) ×2+1) ×2+1) ×2+0=5410
parte frazionaria ((1∶2+0) ∶2+0) ∶2 = 0.12510
Caso 𝒃𝟏=𝟏𝟎
Per calcolare il valore in base 𝑏2(che potrebbe non essere finito) di un numero reale (finito) espresso in base 10, bisogna
distinguere la parte intera dalla parte frazionaria ed operare in modo differente:
Parte intera:
• L’algoritmo di conversione ha sempre termine e consiste nell’effettuare iterativamente delle divisioni per la nuova base
𝑏2, fermandosi solo quando si ottiene un quoziente nullo.
• I resti delle divisioni effettuate, presi in ordine inverso a quello con cui sono stati calcolati, formano la parte intera del
numero convertito.
• I resti ottenuti sono dei numeri decimali il cui valore è < 𝑏2.
• Se 𝑏2 > 10, per formare il numero nella nuova base, ai resti decimali vanno sostituiti (se necessario) i corrispondenti
simboli della nuova base di numerazione.
Parte frazionaria:
• Si moltiplica ripetutamente per la base 𝑏2 e si tolgono le parti intere che, prese nell’ordine, formeranno la parte
frazionaria del numero espresso nella nuova base 𝑏2.
• Le parti intere ottenute sono dei numeri decimali il cui valore è < 𝑏2
• Se 𝑏2> 10, per formare il numero nella nuova base ad essi vanno sostituiti (se necessario) i corrispondenti simboli della
nuova base di numerazione.

ESEMPIO
Convertire 93.62510 in base 2
Parte intera: 1011101 Parte frazionaria: 101
•93/2 = 46 con resto 1 •0.625∗2=1.25 parte intera 1
•46/2 = 23 con resto 0 •0.25∗2=0.5 parte intera 0
•23/2 = 11 con resto 1 •0.5∗2=1 parte intera 1
•11/2 = 5 con resto 1 •0.0∗2=0
•5/2 = 2 con resto 1
•2/2 = 1 con resto 0
•1/2 = 0 con resto 1
93.62510 = 1011101.1012 = 0.10111011012×27

LEZIONE 4: ERRORI E ISTRUZIONI


- Errori
• Un processo di risoluzione di un problema scientifico è soggetto numerosi tipi di errore:
 Imprecisione degli strumenti di misura
 Semplificazione nel modello matematico
 Errori di rappresentazione dei dati reali nella memoria del computer
• Uno dei problemi del calcolo scientifico è valutare l’accuratezza del risultato calcolato da un algoritmo

ESEMPIO
Sia 𝑥=10.1294 e una sua approssimazione (generica) 𝑥∗=10.1253 𝑥∗ è
un’approssimazion
Un modo per misurare la bontà della approssimazione è calcolare
e corretta a 2 cifre
𝐸𝐴=|𝑥−𝑥∗|=|10.1294−10.1253|=0.0041=0.41x10−2 decimali
ERRORE ASSOLUTO

•In generale, 𝑥∗ è un’approssimazione corretta di 𝑥 a m cifre decimali se


𝐸𝐴 = |𝑥−𝑥∗|< 10 - 𝑚
•Quindi l’errore assoluto fornisce informazioni sulle cifre decimali esatte.
| y − y ¿| − ( m−1) −m+1

•In generale, 𝑦 è un’approssimazione corretta di 𝑦 a m cifre significative se E R= <10 =10
| y|
•Quindi l’errore relativo fornisce informazioni sulle cifre significative esatte.

ESEMPIO 𝑦∗ è «migliore» di 𝑥∗
perché rispetto a un
Siano
numero molto più
𝑥= 10.1294 e una sua approssimazione (generica) 𝑥∗= 10.1253 grande!
𝑦= 2410.1294 e una sua approssimazione (generica) 𝑦∗= 2410.1253
𝐸𝐴=|𝑥−𝑥∗|=|10.1294−10.1253|=0.0041=0.41x10−2
𝐸𝐴=|𝑦−𝑦∗|=|2410.1294−2410.1253|=0.0041=0.41x10−2 Otteniamo altre
L’ ERRORE ASSOLUTO è lo stesso ma intuitivamente il loro valore è diverso informazioni se lo
«pesiamo» rispetto al
numero approssimato

ESEMPIO
𝑦 e 𝑦∗hanno 6 cifre
𝑦∗ è
- Errori di rappresentazione un’approssimazione
ESEMPIO: corretta a 6 cifre
significative
In un sistema aritmetico floating point normalizzato F = {b=10, t=5, E min= -9, Emax=9}
• 𝑥=10.4534 non è esattamente rappresentabile, quindi si rappresenta con f𝑙(𝑥)=0.10453 x102
• Che errore si commette rappresentando 𝑥con f𝑙(𝑥)?
• Osservazione: La mantissa di f𝑙(𝑥) contiene le cifre significative del numero
|x−x ¿|
• Studiamo l’errore relativo E R= Errore relativo di round-off (di rappresentazione)
|x|
IN GENERALE:
• 𝑥= 𝑓×𝑏𝑒, f𝑙(𝑥)=𝑓′×𝑏𝑒 con 1/𝑏 ≤ 𝑓 < 1
• 𝑓 e 𝑓′ hanno t cifre in comune
• Quindi
|x−fl ( x )| |f −f '| 1−t | x−fl ( x )| |f −f '| b
( 1−t )
E R= = ≤b ER= = ≤
|x| |f | |x| |f | 2
Troncamento Arrotondamento
• Il massimo errore relativo che si commette rappresentando 𝑥 con f𝑙(𝑥) si dice: Massima Accuratezza Relativa
• e si esprime come u=max ⁡〖∨x−fl( x )∨¿ ¿
• È una COSTANTE DELLA MACCHINA: è diversa per ogni macchina
• Esempi:
•F = {b=10, t=5, Emin=-9, Emax=9} u = 0.5 x 10 -4
•F = {b=2, t=23, Emin=-127, Emax=128} (IEEE s.p.) u=2-23~ 0.119x10-6
•F = {b=2, t=52, Emin=-1023, Emax=1024} (IEEE d.p.) u=2-52~ 0.222x10-15

 Linguaggio macchina
• Nelle locazioni di memoria è possibile memorizzare solo sequenze di bit.
• L’insieme di istruzioni rappresentate come sequenze di bit è detto LINGUAGGIO MACCHINA.
• In un linguaggio macchina ad ogni operazione che l’ALU può eseguire corrisponde un codice operativo.
• È l’unico linguaggio direttamente eseguibile dal calcolatore.
• Il linguaggio macchina di un calcolatore non è eseguibile su calcolatori con architettura differente.

| |
Per eseguire 2 * 4 + 3
Fase 1:
• Prelevare i dati (2 e 4) da locazioni 1000 e 1001
• Eseguire 2 * 4
• Memorizzare il risultato (8) in locazione 1100
Fase 2:
• Prelevare i dati (8 e 3) da locazioni 1100 e 1010
• Eseguire 8 + 3
• Memorizzare il risultato (11) in locazione 1110
ESEMPIO DI LINGUAGGIO MACCHINA
MOLTIPLICAZIONE:
• Codice operativo (c. o.) 0010 Codice operativo Indirizzo Op1 Indirizzo Op2 Indirizzo Risultato

• Istruzione a tre indirizzi 0010 1000 1001 1100


• 2*4 si codifica: 0010 1000 1001 1100
ADDIZIONE:
• Codice operativo (c. o.) 0001 Codice operativo Indirizzo Op1 Indirizzo Op2 Indirizzo Risultato

• Istruzione a tre indirizzi 0001 1100 1010 1110


• 8+3 si codifica: 0001 1100 1010 1110
Allora in questo linguaggio macchina 2*4+3 si codifica:
• 0010 1000 1001 1100
• 0001 1100 1010 1110
• Le istruzioni sono caricate una alla volta dal programma in memoria nella Control Unit
• La CU decodifica i codici operativi
• Si possono avere anche istruzioni a 1 o 2 indirizzi
| |
• Occorrono parecchie istruzioni anche per semplici operazioni.
• Complicato da leggere:
• Del tutto non leggibile per i non addetti ai lavori
• Facilmente soggetto ad errori di programmazione
• Necessita di una profonda conoscenza dell’hardware

- Linguaggio assembly
• Sostituiamo
• Il codice operativo con un nome che ne ricordi la funzione (es. add, mult...)
• L’indirizzo di un dato con un nome che viene dato alla parola di memoria
• Otteniamo il Linguaggio assemblativo (o Assembly)
• Stessa struttura dell’istruzione, ma più comprensibile!!!
| |
ASSEMBLY
MOLTIPLICAZIONE:
• Codice operativo (c. o.) 0010
• Istruzione a tre indirizzi
• 2*4 si codifica: 0010 1000 1001 1100
• In Assembly: mult A B P
ADDIZIONE:
• Codice operativo (c. o.) 0001
• Istruzione a tre indirizzi
• 8+3 si codifica: 0001 1100 1010 1110
• In Assembly: add P C S
| |
• Un programma scritto in Assembly non è eseguibile direttamente dal calcolatore.
• È necessario un programma che traduca l’Assembly in linguaggio macchina (programma assemblatore o Assembler).
• Fase 1: traduzione del programma assembly in linguaggio macchina.

• Fase 2: esecuzione del programma in linguaggio macchina

- Assembler
• Preleva una istruzione in assembly dalla memoria (dati
dell’assemblatore).
• Sostituisce mediante una tabella il nome dell’operazione con il
corrispondente codice operativo.
• Sostituisce al nome delle parole in memoria il corrispondente
indirizzo.
• Memorizza l’istruzione in linguaggio macchina (risultati
dell’assemblatore).
• Il linguaggio assemblativo risolve alcuni problemi del linguaggio
macchina: leggibilità, maggiore facilità di programmazione.
• Rimangono altri problemi
• profonda dipendenza dalla macchina,
• codici lunghi anche per semplici problemi.

- Linguaggi ad alto livello


•Già dagli anni ’50 del XX sec. Sono nati linguaggi orientati alle applicazioni:
• FORTRAN (1954): FORmula TRANslator, per usi scientifici;
• LISP (1959): LISt Processor, per l’intelligenza artificiale;
• COBOL (1960): COmmon Business-Oriented Language, per usi commerciali.
•Classificabili generalmente in:
• Imperativi (Assembly, Fortran, Cobol, Basic, APL, …)
• Strutturati (C, pascal, ADA, Fortran 90, …)
• Ad oggetti (C++, Java, PHP, Python, …)
• Paralleli (Occam, HPF Fortran, Linda, …)
• Di scripting (Perl, Javascript, PHP, Python, …)
• Per database (Progress, Oracle, …)
• Le due istruzioni in linguaggio assembly: Mult A B P --- Add P C S

S=A*B+C (Fortran) S:=a*b+c; (Pascal)


S=a*b+c; (linguaggio C) S=a*b+c (Python)
Possono essere riscritte in linguaggio ad alto livello come

• Meno istruzioni e più vicino ad un linguaggio matematico


• Anche i linguaggi ad alto livello hanno bisogno di programmi traduttori per la traduzione in linguaggio macchina
• Due tipi di programmi traduttori: Compilatori e Interpreti.
L’interprete:
1.Preleva un’istruzione dalla memoria,
2.La traduce in linguaggio macchina,
3.Esegue immediatamente l’istruzione, prelevando dalla memoria i dati necessari.
• In definitiva l’esecuzione del programma avviene in una unica fase, che fornisce direttamente il risultato.
Il compilatore:
1.Preleva un’istruzione dalla memoria,
2.La traduce in linguaggio macchina,
3.La conserva in memoria.
• In definitiva l’esecuzione del programma avviene in due fasi:
Fase 1: traduzione del programma scritto in linguaggio ad alto livello in linguaggio macchina;
Fase 2: esecuzione del programma scritto in linguaggio macchina (in un momento successivo).

• Con l’interprete l’esecuzione è costantemente sotto controllo dell’interprete:


• è possibile fornire un’istruzione alla volta e controllare subito se è corretta,
• utili in fase di debugging o per ambienti didattici.
• Le due fasi distinte richieste dal compilatore, rendono possibile la memorizzazione del programma scritto in linguaggio
macchina, che è quindi possibile eseguire numerose volte senza perdere il tempo della traduzione.
• Sono più efficienti.
• I linguaggi C e Fortran (i più usati per il calcolo scientifico) sono linguaggi COMPILATI.
• Python è un linguaggio INTERPRETATO.
• Creato alla fine degli anni ‘80 da Guido van Rossum.
• Tra i 10 linguaggi più usati attualmente.
• Molto popolare per applicazioni web, per gli ambienti didattici e spesso nel calcolo scientifico.
LEZIONE 5: HARDWARE
- Struttura di un calcolatore
• Un computer è fatto di diverse componenti collegate per gestire le diverse funzionalità in maniera trasparente all’utente.
Il cuore è nella SCHEDA MADRE.
• La scheda madre contiene quasi tutti i circuiti a cui sono collegati:
 Il microprocessore: Su questo slot si monta la (o LE) CPU, che controlla tutte le funzioni del computer,
composta di una o più CU/ALU.
 La memoria: Su questi slot si montano i banchi di memoria RAM.
 L’alimentatore: L’alimentatore si collega alla scheda madre attraverso appositi connettori.
 Tutti gli altri dispositivi: Slot di espansione per inserire schede contenenti altri componenti elettronici come una
scheda video, o un fax/modem interno ….
• Ci sono poi altri connettori per tutti i dispositivi esterni, a volte collegati tramite BUS o tramite porte che sporgeranno
all’esterno del CASE.
• Il microprocessore è una (o più) CPU costruite su sottili lamine di silicio (chip), ognuna delle quali contiene milioni
(miliardi) di piccolissimi «interruttori», i TRANSISTOR.
• I transistor sono collegati tra loro da tracce estremamente sottili di alluminio. Si formano in questo modo dei circuiti che
elaborano i dati.
• Ogni CPU è fatta di:
 Control Unit: coordina tutte le attività del calcolatore
• Preleva dalla memoria le istruzioni (fetch)
• Le interpreta (decode)
• Preleva i dati dalla memoria (load)
• Esegui l’istruzione (execute)
• Memorizza il risultato (store)
• Determina la successiva istruzione da eseguire
 ALU: l’unità che esegue le operazioni logiche ed aritmetiche, eseguendo i comandi provenienti dall’unità di
controllo.
• Nelle immediate vicinanze del processore sulla scheda c’è una memoria ROM (Read Only Memory).
• La memoria ROM è una memoria non volatile (statica ed inalterabile) il cui contenuto viene predisposto dalla casa
produttrice e non può essere modificato direttamente dall’utente.
o La memorizzazione di bit in una ROM è paragonabile alla fusione di piccoli fusibili (in posizione aperta -1- o
chiusa -0).
• Anche lo spegnimento non ha nessun effetto sulla ROM, non altera i dati, che verranno richiamati automaticamente
quando il computer verrà riacceso
• Contiene in genere i programmi e le istruzioni necessarie all’avvio (boot) e le istruzioni base (microcodice).
• Nei dispositivi moderni è aggiornabile tramite opportune procedure.
 È in realtà realizzata con una tecnologia flash, dunque non «strettamente» ROM
 Il contenuto memorizzato si dice firmware

- Gerarchia di memoria
• Il processore è collegato alla MEMORIA. (Meglio dire ALLE MEMORIE)
• 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.
• Tutte queste memorie sono organizzate gerarchicamente, ovvero esiste una Gerarchia di memoria.
• Le principali caratteristiche che differenziano le varie
memoria sono: il tempo di accesso e la dimensione.
• Memorie di alto livello: veloci (pochi ns) e piccole (MB
GB); adatte a fornire dati alla CPU ad una adeguata velocità;
utilizzate solo dai programmi in esecuzione.
• Memorie di basso livello: lente (alcuni ms e grandi TB);
adatte a conservare grandi quantità di dati e programmi in
maniera permanente; utilizzate per conservare dati e
programmi non utilizzati dalla CPU in quel momento.

- Registri
• I registri sono memorie molto piccole (e costose) ad alta velocità di accesso, e per questo di solito molto vicine se non
interne alla struttura del microprocessore. Possono essere generici o speciali.
• Quelli generici fungono da luoghi di memorizzazione temporanea per i dati elaborati conservano i dati in ingresso e
forniscono uno spazio di memorizzazione immediato per i risultati ottenuti.
• Per eseguire un’operazione su qualunque dato la CU deve prima trasferirlo nei registri generici, informare l’ALU della
nuova posizione e della posizione in cui portare il risultato.
• Per trasferire i dati, l’unità centrale e la memoria principale (o centrale) sono collegate da un insieme di fili denominati
BUS.
• Tramite il bus, la CPU è in grado di leggere i dati dalla memoria principale (o centrale) nei registri, specificando
l’indirizzo della relativa cella di memoria.
• In modo simile la CPU può scrivere dati dai registri in memoria, attraverso l’indirizzo della cella di destinazione.

- Cache
• Tra la memoria principale e i registri c’è in genere un ulteriore livello (o anche più livelli) detto di CACHE.
• La cache si può vedere come una memoria di appoggio che è più veloce e più «vicina» al processore della memoria
principale, ma più piccola.
• Per velocizzare il tempo di accesso medio alla memoria principale, quando la CU porta un dato dalla memoria attraverso
il BUS, lo porta con altri dati a lui «vicini» e lascia tutto in cache prima di portare il necessario nei registri.
 È infatti in genere molto probabile che si riaccederà agli stessi dati o a dati vicini nelle prossime operazioni, e
trovarli già in cache accelererà il loro recupero (principio di località).
 Solo quando i dati non sono in cache verranno cercati nella memoria principale, e dunque saranno portati in cache
in sostituzione di altri riportati in memoria (eventualmente variati rispetto a quando sono stati caricati).

- Memoria principale (RAM)


• La memoria principale è organizzata in singole celle dotate di un indirizzo a cui è possibile accedere indipendentemente
secondo le necessità.
• Tale memoria si chiama di solito RAM (Random Access Memory) per indicare la capacità di accedere alle celle in
qualsiasi ordine.
• Questa accessibilità in modo casuale della memoria principale la differenzia nettamente dai sistemi di memoria di
massa.
• I bit sono memorizzati in piccole cariche elettriche che si dissipano rapidamente.
• Necessitano di un circuito di refresh per essere ricaricati più volte al secondo: la RAM è allora una memoria volatile, e
per questo si dice memoria dinamica (DRAM).
• A volte si applicano tecniche supplementari per ridurre il tempo necessario a prelevare i dati (Synchronous DRAM-
SDRAM).

- Memoria di massa
• I computer sono forniti di dispositivi aggiuntivi chiamati sistemi di memoria di massa (o memoria secondaria)
 Dischi magnetici,
 CD, DVD, BluRay, …
 Nastri magnetici,
 Unità flash,
 Dischi a stato solido.
• Non sono volatili (o lo sono meno); Hanno grandi capacità di memorizzazione; Possono in genere essere facilmente
rimossi, allontanati, sostituiti; Sono lenti; Sono più esposti ai guasti meccanici.

- Hard disk
• Uno degli esempi più comuni di memoria di massa è il disco magnetico o hard disk drive (HDD), che conserva i dati su
un sottile disco rotante con rivestimento magnetico.
• Le testine di lettura/scrittura sono poste sopra e sotto
il disco, in modo che durante la rotazione ciascuna
testina percorra un cerchio chiamato traccia.
• Riposizionando le testine di lettura/scrittura lungo il
raggio del disco è possibile accedere a tracce
concentriche diverse.
• Spesso i sistemi a disco consistono di più dischi
montati su un perno comune uno sull’altro, con spazio
sufficiente affinché le testine si spostino tra i piatti,
muovendosi simultaneamente.
• Ogni volta che le testine sono posizionate diventa accessibile un nuovo insieme di tracce, chiamato cilindro.
• Poiché una traccia può contenere più informazioni di quante se ne vogliano manipolare contemporaneamente (di solito),
essa è anche divisa in archi, detti settori, su cui i dati vengono registrati come una stringa continua di bit.
• Nei sistemi a disco più semplici ciascuna traccia all’interno di un sistema a dischi contiene lo stesso numero di settori, e
ogni settore contiene lo stesso numero di bit, quindi i bit posti nei settori delle tracce più vicine al centro del disco sono
memorizzati in modo più compatto rispetto a quelle vicine al bordo esterno.
• La capacità di un sistema a dischi dipende dal numero di piatti utilizzati dalla densità con cui sono disposti settori e
tracce. I sistemi più capaci contengono oggi da tre a sei piatti su un perno comune.
• Il tempo di accesso ai dati su un disco magnetico dipendono dal:
 Tempo di posizionamento: della testina da una traccia a un’altra.
 Ritardo di rotazione: metà del tempo per eseguire una rotazione completa, cioè tempo medio perché la testina
raggiunga un particolare dato sulla traccia.
• Si dovrà considerare poi la velocità di trasferimento: relativa al tempo per portare un dato unitario dal disco alla
memoria principale o viceversa.
• Per aumentare la velocità di rotazione le testine non toccano il disco ma «fluttuano» sopra la superficie a distanza tanto
piccola da poter essere riempita da una sola particella di polvere infiltrata che distruggerebbe disco e testina.
 I dischi vengono venduti sigillati dalla fabbrica.

- Sistemi ottici
• I Compact Disc (CD) sono dischi di diametro 12 cm in materiale riflettente con un rivestimento protettivo chiaro.
• Le informazioni si memorizzano creando minuscoli fori sulle superfici riflettenti e si recuperano tramite un raggio laser
(rosso) che rileva le irregolarità sulla superficie quando il disco gira.
• La traccia è una sola e gira a spirale sulla superficie del disco, come il solco dei dischi in vinile, ma in senso contrario,
cioè dal centro verso l’esterno.
• La traccia è divisa in settori da 2 KB
• I Digital Versatile Disc (DVD) sono costituiti da più livelli
semitrasparenti che funzionano come superfici distinte
quando vengono lette da un raggio puntato con precisione, e
sono molto più capaci dei CD.
• I Bluray Disc (BD) sono letti tramite un laser la cui luce
rientra nello spettro blu-viola (e non rosso), che può
focalizzarsi con precisione altissima, per cui tali dischi
possono essere capaci anche 5 volte più dei DVD.

- Unità flash
• Una delle caratteristiche comuni ai sistemi di memoria di massa basati sulle tecnologie magnetica e ottica è che per
recuperare i dati è necessario un movimento fisico.
• Sono enormemente lenti rispetto ai circuiti elettrici della memoria RAM, per esempio.
• La tecnologia flash memorizza i bit inviando segnali elettrici direttamente al dispositivo di memorizzazione, dove gli
elettroni vengono intrappolati in piccole celle di biossido di silicio, alterando così le caratteristiche di piccoli circuiti
elettrici.
• Le celle possono contenere gli elettroni per molti anni anche senza alimentazione esterna, perciò tale tecnologia è ideale
per la memorizzazione portatile e non volatile dei dati.
• I dati si indirizzano in piccoli gruppi ma le cancellazioni ripetute danneggiano progressivamente le celle di biossido di
silicio, dunque questa tecnologia non è adatta ad utilizzi in cui il contenuto si riscrive più volte al secondo.
• Non è sensibile agli shock fisici, dunque è perfetta per gli utilizzi portatili:
 Dischi per laptop e portatili
 Schede di memoria Secure Digital (SD)
 Piccoli dispositivi USB
• Dischi a stato solido (SSD), o unità flash di grandi capacità, possono sostituire le unità disco magnetiche, con i vantaggi
di maggiore resistenza, minore rumorosità, e minori tempi di accesso. Ma sono ancora molto più costosi e hanno un
periodo di vita limitato.

LEZIONE 6: SISTEMA OPERATIVO, PROCESSI E ALGORITMI


- Sistema operativo
• A partire dagli anni ‘60 si sono sviluppati i:
 Sistemi Operativi con Multiprogrammazione (Multitasking)
 capacità di tenere in memoria più programmi contemporaneamente
 Mentre un programma esegue operazioni di I/O (prog2), un altro
programma (prog3) può utilizzare la CPU
 Il memory manager è incaricato di tenere traccia della memoria
occupata.

- Sistema operativo: multitasking


• 3 programmi iniziano l’esecuzione nello stesso istante.
 P1 richiede 24 msec di CPU
 P2 richiede 3 msec di CPU
 P3 richiede 3 msec di CPU
• Tempi di completamento:
 P1 termina dopo 24 msec
Più programmi vengono caricati
 P2 termina dopo 27 msec (24 attesa + 3 esecuzione)
contemporaneamente per
 P3 termina dopo 30 msec (27 attesa + 3 esecuzione) essere eseguiti
• Tempo medio di completamento = (24+27+30) /3 = 27 msec

- Sistema operativo: time sharing


• Se in memoria è presente un programma che richiede molto tempo di calcolo, altri programmi più brevi devono
attendere la fine del primo programma / tempo medio di elaborazione elevato
SOLUZIONE
• Assegnare ad ogni programma un tempo massimo di utilizzo della CPU (time slice)
• Se si supera tale limite il programma viene sospeso e si manda in esecuzione un altro programma (time sharing)
• Un programma del sistema operativo (dispatcher) si occupa della sospensione e della ripresa dei programmi
• 3 programmi iniziano l’esecuzione nello stesso istante. Time slice = 5 msec
 P1 richiede 24 msec di CPU
 P2 richiede 3 msec di CPU
 P2 richiede 3 msec di CPU
• Tempi di completamento
 P1 termina dopo 30 msec (6 attesa + 24 esecuzione) I programmi caricati
contemporaneamente si
 P2 termina dopo 8 msec (5 attesa + 3 esecuzione)
 P3 termina dopo 11 msec (8 attesa + 3 esecuzione)
• Tempo medio di completamento = (30 + 8 + 11) /3 = 16,33 msec.

- Sistema operativo
• Un programma (scheduler) si occupa dell’ordine con cui i programmi devono essere in esecuzione
• Con la multiprogrammazione e il time sharing si riducono i tempi medi di attesa e ogni utente ha la sensazione di essere
l’unico utente del sistema.

- Processi
• Un programma in esecuzione prende il nome di processo
• Un processo attraversa varie fasi:
 New: viene allocato lo spazio in memoria
 Ready: il processo è pronto, ed aspetta il suo turno
 Running: il processo utilizza la CPU
 Waiting: il processo attende il completamento di un’operazione di I/O
 Terminated: viene liberato lo spazio in memoria
• C’è sempre un solo processo running (per ogni CPU)
• Ci sono in genere molti processi ready o waiting

- Problema: frammentazione
• Con la multiprogrammazione si alloca ad un processo uno spazio della
dimensione del processo stesso
• Quando i processi finiscono si creano dei buchi (holes) in memoria
• Resta, dunque, a volte anche parecchio spazio disponibile in memoria ma
non utilizzabile perché non contiguo
 Si verifica il fenomeno della FRAMMENTAZIONE.

- SOLUZIONE: MEMORIA VIRTUALE


• Il meccanismo della MEMORIA VIRTUALE permette allocazione non
contigua alloca la memoria fisica ai processi ovunque essa sia disponibile,
riempiendo i buchi.
• Si divide la memoria fisica in blocchi di dimensione fissa chiamati blocchi
(o frame).
• Si divide il processo in blocchi della stessa dimensione chiamati pagine.
• Per eseguire un processo di n pagine, è necessario trovare n frame liberi
prima di caricare il programma, che possono essere distanti tra loro ma
verranno considerati collegati come se fossero vicini.

- Problema: memoria a capacità limitata


• Il time sharing e la memoria virtuale permettono l’accesso alla CPU a molti programmi residenti in memoria
• Ma la memoria ha una capacità limitata
• Come fare a tenere numerosi programmi (anche grandi) contemporaneamente in memoria?

- Soluzione: swapping
• L’idea è di conservare:
 in memoria centrale solo la pagina con la sezione di codice da eseguire
 in memoria di massa il resto delle pagine
• Un programma del sistema operativo (swapper) si occupa della sostituzione delle pagine in memoria.
• La memoria virtuale è allora lo spazio di indirizzamento effettivamente utilizzabile dall’utente:
 Lo scambio tra memoria centrale e disco è automatico;
 Lo spazio logico degli indirizzi è più grande dello spazio fisico.
• In questo modo un maggior numero di processi può concorrere all’uso della CPU.
• NOTA: Sono meccanismi analoghi a quelli per lo scambio di informazioni tra memoria principale e memorie cache, che
convivono apparendo come un unico sistema di memoria centrale.

- File system
• Dal punto di vista dell’utente, le informazioni sul disco sono organizzate in strutture
chiamati file, che possono essere distribuiti su più settori.
• Il file è la più piccola unità di memoria secondaria accessibile agli utenti, tutti i dati
presenti nella memoria secondaria devono essere organizzati in file.
• Un sistema operativo può gestire milioni di file, di differenti utenti, di tipi
differente, necessità di organizzare logicamente i file.
• L’organizzazione logica dei file di un sistema operativo è chiamata FILE SYSTEM.
• Il File system organizza i file e gestisce l’accesso ai dati.
• È responsabile dell’integrità dei file e della gestione dei metodi di accesso
(lettura/scrittura).
• Nasconde all’utente l’organizzazione fisica del disco.
• Dà all’utente una visione dei file indipendente dai dispositivi fisici.
• Lo strumento più comune usato per realizzare un file system è la directory (o cartella).
• Di solito, gli elementi di una directory possono essere file o altre directory in maniera da creare una struttura ad albero
• Una directory principale (root directory, master file directory) indica la radice dell’albero dalla quale partono le
directory di secondo livello.
• Windows e Unix sono organizzati in questo modo.

Una catena di directory collocate all’interno di altre directory è


chiamata percorso (path).
ESEMPIO
/usr/joe/game è il path della directory game in un sistema UNIX
C:\usr\joe\game è il path della directory game in un sistema
WINDOWS

- Componenti del sistema operativo


• La struttura dei moderni sistemi operativi nel tempo si è «complicata».
• La parte interna si chiama kernel (nocciolo) e contiene le funzionalità di base del sistema.
• È stato completato aggiungendo funzionalità attraverso l’introduzione e l’inclusione di altri programmi per far fronte a
esigenze di efficienza (per il sistema) e semplicità di uso (per l’utente).
• Principali sottosistemi di un sistema operativo sono:
1. Gestione dei programmi in esecuzione (nel kernel);
2. Gestione della memoria centrale (nel kernel);
3. Gestione della memoria di massa e del file system (nel kernel);
4. Gestione delle periferiche (nel kernel);
5. Gestione dell’I/O;
6. Interfaccia utente grafica (GUI).
 Parte fondamentale di una GUI attuale è il window
manager (gestore di finestre), che alloca parte dello
schermo, le finestre appunto, e associa ad ognuna di
esse un’applicazione di cui tenere traccia. Il window
manager gestisce anche il puntatore sullo schermo.

LEZIONE 7: ALGORITMI E PROGRAMMAZIONE E INTRO PYTHON


- Creatività
• Il concetto di algoritmo evidenzia come l’informatica sia un campo intrinsecamente creativo.
• Scoperta e applicazione di nuovi algoritmi sono attività umane che derivano dal desiderio innato di applicare i nostri
strumenti alla risoluzione dei problemi che ci circondano.
• L’informatica, dunque, non si limita ad ampliare le forme espressive delle arti visive, linguistiche e musicali, ma rende
possibili nuove modalità di espressione (digitale).
• La creazione di grandi sistemi software ha poco a che fare con il seguire le istruzioni di una ricetta, assomiglia più al
concepire una nuova, grande scultura.
• Immaginare forma e funzioni richiede un’attenta pianificazione.
• Costruire i componenti richiede tempo, cura del dettaglio e abilità.
• Il prodotto finito incarna la personalità, le idee, la sensibilità e l’estetica dei suoi creatori, come qualsiasi opera creativa.
- Programmazione
• L’hardware del computer è in grado di eseguire soltanto passaggi logici semplici, ma le astrazioni fornite dai linguaggi
di programmazione permettono agli esseri umani di ragionare su problemi molto complessi e di codificare delle soluzioni.
• Programmazione è la capacità di risolvere problemi fornendo algoritmi eseguibili, ovvero PROGRAMMI, e rimane
l’abilità informatica fondamentale
• È importante distinguere tra algoritmo e la sua rappresentazione: come distinguiamo una storia dal libro che la racconta.
• Se il libro che racconta la storia è tradotto in un’altra lingua, o ripubblicato in un formato diverso, cambia la
rappresentazione, ma la storia è sempre la stessa.
• Allo stesso modo, un algoritmo può essere rappresentato in molti modi.
• La rappresentazione è importante quando dobbiamo comunicare l’algoritmo a qualcuno (o qualcosa) altro.
• è importante che sia chiaro il livello di dettaglio a cui l’algoritmo deve essere descritto, che chi lo deve
comprendere o eseguire abbia tutti gli strumenti per farlo e che la rappresentazione non introduca ambiguità
• Cominciamo col chiarire dei termini:
• PROGRAMMA è la rappresentazione di un ALGORITMO
• PROCESSO è un programma (quindi un algoritmo) in esecuzione.

- Pseudolinguaggi
• In generale la scrittura di un algoritmo (prima che diventi programma per una macchina) avviene in una sorta di
«versione rilassata» di un linguaggio di programmazione, che consente di esprimere informalmente le idee e descriverle
in maniera sufficientemente chiara.
• Questo passaggio è estremamente utile quando l’algoritmo da progettare è molto grande e complesso, troppo per stare
tutto costantemente nella mente umana.
• Pseudolinguaggi molto usati sono quelli che vengono dall’Algol o dal Pascal.
• Quello che vedremo più avanti lo chiameremo Pascal-Like.
• Sono diventati recentemente molto usati anche pseudolinguaggi più simili a Java e C, in quanto per molti programmatori
sono i più facili da leggere.
• Uno pseudocodice deve avere una notazione coerente e concisa per la rappresentazione delle strutture semantiche
ricorrenti (dichiarazione, assegnazione, confronto, operazioni elementari, cicli…).

- Flow Chart
ALGORITMO
Sequenza di istruzioni non ambigue che in un numero finito di passi risolvono una
classe di problemi.
Un primo pseudolinguaggio per descrivere un algoritmo è il flow chart
Gli elementi del linguaggio sono:
• Ovale (inizio e fine);
• Rettangolo (comandi);
• Rombo (verifica condizione);
• Rettangolo con angolo tagliato (Input);
• Foglio (Output).
ESEMPIO
Problema: calcolare la circonferenza del cerchio per molteplici valori del raggio:
Raggio = 1 SOLUZIONE: circonferenza = 2 ∗ 𝜋 ∗ 1
Raggio = 2.5 SOLUZIONE: circonferenza = 2 ∗ 𝜋 ∗ 2.5
Raggio = 5 SOLUZIONE: circonferenza = 2 ∗ 𝜋 ∗ 5
Alcuni dati in queste soluzioni sono costanti (2 e 𝜋): restano gli stessi per ogni esecuzione.
Altri dati sono variabili (raggio e circonferenza): il raggio sarà dato in input con la variabile R, la circonferenza in output
nella variabile C.

Chiamiamo VARIABILE il nome dato ad una posizione in memoria.


L’istruzione C = 2 ∗ 𝜋 ∗ 𝑅:
• Preleva dalla memoria il contenuto della variabile R
• Lo moltiplica per 2 ∗ 𝜋
• Memorizza il risultato nella variabile C
Questo perché il segno «=» è una operazione di assegnazione: assegniamo a C il valore
risultato della moltiplicazione.
Perché l’algoritmo funzioni, la variabile R deve essere definita, cioè deve avere un
valore prima che sia eseguita la moltiplicazione, ovvero che R sia utilizzata come input
di un’operazione: dobbiamo aver assegnato un valore ad R.
Una variabile avrà un tipo, a seconda del tipo verrà interpretato il valore contenuto nella
posizione di memoria.
Alcuni linguaggi richiedono di dichiarare esplicitamente il tipo delle variabili prima di
usarle: linguaggi fortemente tipizzati, eventualmente con possibilità di cambiare il tipo di una variabile (promozione di
tipo), entro certe regole, nel corso del programma.
Altri linguaggi (tra i quali Python) utilizzano degli automatismi per dedurre il tipo delle variabili.

- Pascal-like
• La prima scrittura di un algoritmo, prima ancora che diventi un codice in un linguaggio
comprensibile da una macchina, dovrebbe avvenire sempre in un linguaggio generale ma
che costringa allo sforzo di astrazione e permetta poi di passare facilmente ad altri
linguaggi effettivi.
• Per questo scopo è stato inventato il Pascal like un linguaggio per la descrizione degli
algoritmi (anche chiamato pseudo-linguaggio) derivato dal Pascal, che costringe a
sviluppare algoritmi in maniera più strutturata del semplice flow chart.
• L’istruzione read R legge un valore dall’unità di input e lo assegna alla variabile R
• L’istruzione print C visualizza sull’unità di output il contenuto della variabile C
• In Pascal-like l’istruzione di assegnazione è in genere indicata con la notazione:=.
Qui e in seguito scriviamo solo = per mantenere la somiglianza con Python.
• In Pascal-like le variabili devono essere dichiarate PRIMA che cominci il programma.
• In una istruzione del tipo «R = P» come distinguere i due casi seguenti?
# Assegna a R il contenuto della variabile P # Assegna a R il carattere P (costante)
• In una istruzione del tipo «C = 6», come distinguere i due casi seguenti?
# Assegna a C il numero intero 6 (costante) # Assegna a C il carattere 6 (costante)
• Bisogna stabilire modi diversi di riferirsi a costanti diverse, e che siano anche diversi dalla scrittura dei nomi di variabili.
• Le costanti di tipo carattere sono racchiuse tra una coppia di apici. # Esempio: ‘casa’, ‘Napoli’, ‘Maria’
• Le costanti di tipo logico sono racchiuse tra una coppia di punti.
# Esempio: .true. , .false.
• Le costanti di tipo intero sono sequenze di cifre eventualmente con segno.
# Esempio: +80, -45, 981
• Le costanti di tipo reale sono sequenze di cifre con il punto decimale.
# Esempio: 45.23, 0.0032, -23.12,
• Per il tipo reale è possibile utilizzare anche la notazione esponenziale.
# Esempio: 12.3e5, 0.e0, 0.1e-6
• Nell’algoritmo per il calcolo della circonferenza il valore del simbolo (costante) 𝜋 è ambiguo.
• Specificando il valore come una costante di tipo reale si ottiene la versione finale dell’algoritmo.
• L’assegnazione di un valore ad una variabile può avvenire in due modi.
• Tramite lettura (istruzione read).
• Tramite assegnazione (operatore =).
• Utilizzando una ulteriore variabile (PG), l’algoritmo per il calcolo della circonferenza
può essere riscritto come riportato.
• Tutte le variabili devono essere definite prima di essere utilizzate.
• Il valore dell’espressione deve essere dello stesso tipo di quello della variabile a cui è
assegnato. Se PG fosse stata dichiarata di tipo intero, sarebbe stato un errore assegnargli
un valore reale.

• Nella definizione di una variabile, prima si valuta l’espressione al secondo membro, e dopo si
assegna il valore ottenuto alla variabile al primo membro.
• Una variabile può essere utilizzata più volte ridefinendo il suo valore nel corso dell’algoritmo.

-
- PASCAL-
LIKE:
strutture di
controllo
• Spesso in un algoritmo occorre eseguire operazioni diverse a seconda del valore (vero o falso) di una condizione logica.
ESEMPIO:
Trovare il massimo tra due numeri.
Dati di input: i due numeri (A e B)
Dati di output: il massimo (MAX)
Idea: si confrontano i due numeri (A e B). Se il primo è maggiore del secondo il massimo
(MAX) è A, altrimenti è B.
Come si realizza?
• In Pascal like la struttura di selezione è realizzata con la struttura
if-then-else-endif.
• In generale:
1. Viene valutata l’espressione logica (if)
2. Se è vera viene eseguito il blocco di istruzioni prima di else (Istr 1)
3. Se è falsa viene eseguito il blocco di istruzioni dopo di else (Istr 2)
• L’istruzione endif segnala la fine della struttura.

Nella valutazione dell’espressione logica è possibile verificare la veridicità di una o più condizioni
basate su operatori relazionali
> (maggiore) < (minore) == (uguale) /= (diverso)
combinate tra loro mediante operatori logici
AND OR NOT. In Pascal-like l’istruzione di assegnazione è in
Esempio: genere indicata con la notazione := e
l’espressione per il controllo dell’uguaglianza
(A > B) AND (X == 0)
si indica con il semplice =. Qui e in seguito
• Il risultato dell’espressione logica deve scriviamo solo = per le assegnazioni e == per i
essere sempre vero o falso. controlli di uguaglianza, per mantenere la
• Gli operatori relazionali vengono valutati somiglianza con Python.
prima degli operatori logici.

+ PYTHON INRODUZIONE

LEZIONE 8: STRUTTURE DI ITERAZIONE E PYTHON


- PASCAL-LIKE: strutture di iterazione
• Spesso in un algoritmo è necessario ripetere più volte lo stesso blocco di istruzioni
Esempio:
• Somma di 5 numeri
• Dati di input: i 5 numeri
• Dati di output: la somma
• Idea: leggere un numero alla volta (NUM) e sommarlo ad una
variabile inizialmente posta uguale a zero (S)

• In Pascal like la struttura di iterazione è realizzata con la struttura


for - endfor
• Vengono eseguite le istruzioni tra for e endfor per tutti i valori dell’indice i (o I), compresi tra il primo e l’ultimo
valore.
• L’indice i (o I) è una variabile a tutti gli effetti e va dichiarata.
• Può in realtà chiamarsi in qualsiasi altro modo.

Algoritmo
SOMMA DI 5 NUMERI

• In generale, si esegue il blocco di istruzioni per tutti i valori dell’indice I


compresi tra le variabili intere.
Start: primo valore della variabile I
ed
End: ultimo valore della variabile I
• È possibile specificare un valore opzionale anche negativo (Passo) che
rappresenta l’incremento della variabile I
• Se manca, Passo=1

Algoritmo
Somma di N numeri
Esempio
Qual è il risultato della
somma se nell’algoritmo
Start=11,
Start=1 End=5, Step=-2?
End=N
Passo=1

+ PYTHON

LEZIONE 9: STRUTTURE DI ITERAZIONE + PYTHON


- PASCAL-LIKE: strutture di iterazione
• Le strutture di controllo possono essere innestate l’una nell’altra.
• La prima struttura che si apre deve essere l’ultima che si chiude.
• In caso di più strutture for-endfor è necessario utilizzare indici diversi.
• Spostare verso destra le istruzioni interne ad una struttura aiuta la leggibilità
dell’algoritmo: INDENTAZIONE.

IDEA
• Leggere un numero alla volta (NUM) e confrontarlo con la
variabile che contiene il massimo dei numeri esaminati (MAX).
• Se NUM è maggiore di MAX si cambia il valore di MAX.
• Occorrono 2 strutture innestate:
• «for – endfor» per leggere i numeri uno alla volta;
• «if-endif» per confrontare NUM e MAX. ESEMPIO
Input:
• N = 5 (la quantità di numeri
da esaminare)
• NUM = 5; 6; 1; 8; 2
Algoritmo Output:
Massimo tra N numeri • Il massimo MAX=8

Input:
• N (la quantità di numeri da esaminare)
• NUM = ogni volta un numero
Output:
• Il massimo MAX

+ PYTHON
LEZIONE 10: RIPETIZIONE PROGRAMMAZIONE + PYTHON
LEZIONE 11: VARIABILI STRUTTURATE E ARRAY + PYTHON
- PASCAL-LIKE: variabili strutturate
• Dati due vettori geometrici A e B di lunghezza N
A = (a1, a2, …, aN)
B = (b1, b2, …, bN)
• Calcolare il vettore C, somma dei precedenti due
C = (c1, c2, …, cN)
• Dove ci = ai + bi per ogni i=1, ..., N
• È necessario conservare tutti i valori di C
• Individuiamo con un singolo nome un insieme di dati organizzati secondo un fissato criterio
• Ogni dato viene trattato come una singola variabile
• VARIABILI STRUTTURATE
• Le variabili strutturate definiscono il modo di organizzare ed accedere in maniera efficiente gruppi di dati.
• Caratteristica comune: omogeneità degli elementi che compongono la struttura.
• Varie strutture dati: alberi, liste, pile, code, heap, … array.

- PASCAL-LIKE: array
• Gli array sono strutture dati che nascono con l’obiettivo di rappresentare in maniera efficiente i principali elementi del
calcolo scientifico:
• vettori e matrici
• Dimensione fissata (non modificabile)
• Tutti gli elementi sono dello stesso tipo
• Si accede agli elementi mediante un indice che indica la posizione del corrispondente elemento
• Osservazione: a secondo dei linguaggi l’indice può partire da:
• 1 (ad es. Fortran)
• 0 (ad es. C, C++, Java, Python)
• Come per tutte le variabili,
prima di utilizzare una struttura dati è necessario dichiararla.
• Dichiarare il tipo della struttura.
• Dichiarare il tipo di elementi.
• Esempio: var NOMI(6): array of character.
• Con la dichiarazione viene determinata la dimensione massima della
struttura.
• La dichiarazione permette al compilatore di riservare un adeguato spazio in
memoria per tutti gli elementi dell’array.
• Gli elementi di un array sono allocati in memoria in locazioni consecutive
(logicamente).

Ma, se consideriamo il tipo string potete scrivere anche…


• Ogni elemento di un array è accessibile mediante un indice.
STRINGA: array di singoli caratteri
• NOMI(i) rappresenta l’i-mo elemento.
• Per le operazioni di I/O è necessario accedere agli elementi di un array, uno alla volta, mediante una struttura di
iterazione for-endfor.
• Osservazioni: l’indice i è una variabile a tutti gli effetti e va dichiarata come variabile intera; è possibile utilizzare solo
una parte dell’array.

IDEA
Algoritmo
Esaminare uno alla volta gli N elementi
Calcolare il
dell’array e incrementare una variabile C
numero di
quando si trova un elemento nullo
ricorrenze
dell’elemento O
in un array

Input:
• N (la lunghezza
EFFETTIVA dell’array A)
• A vettore di N numeri
Output: Il numero di
elementi nulli C
• Mediante gli array è possibile trattare anche tabelle
• array a 2 dimensioni
Esempio
Per memorizzare i voti in varie materie di un gruppo di studenti è
necessaria una tabella dove
• Le righe rappresentano gli studenti
• Le colonne rappresentano i voti nelle diverse materie
Al momento della dichiarazione è necessario definire il numero di righe e il
numero di colonne che compongono l’array
Esempio
var voti(5, 3) : array of integer dichiara una array di interi di 5 righe e 3
colonne
Sono necessari due indici:
• Il primo indice identifica la riga
• Il secondo indice identifica la colonna
voti(i, j) si riferisce al j-mo voto dell’i-mo studente

LEZIONE 12: VARIABILI STRUTTURATE E ARRAY + PYTHON


- PASCAL-LIKE: array 2 dimensioni
• Per un array 2-dimensionale di N righe e M colonne è necessario accedere a
tutti gli elementi, uno alla volta, scorrendo entrambi gli indici
A(i,j) i=1,..,N e j=1,..,M
• Occorrono 2 strutture di iterazione for-endfor innestate.
NOTA BENE: nell’esempio l’indice j varia più velocemente rispetto all’indice i.

• ALGORITMO: somma di due matrici


Date due matrici quadrate A e B di ordine N, calcolare la
matrice C ottenuta come loro somma
C=A+B.
Esempio: se N=3

( )( )( )
1 2 3 5 6 7 6 8 10
1 0 −1 + 0 1 0 = 1 1 −1
3 2 1 7 6 5 10 8 6
Per ogni elemento è necessario calcolare:
C(i,j) = A(i,j)+B(i,j) i=1,..,N j=1,..,N.
• ALGORITMO: scambio di due righe
Data la matrice A di ordine NxM, scambiare la riga r con la riga c.
Esempio: se N=4, M=3, r=2, c=4.

[ ] [ ]
1 3 7 1 3 7
2 4 8 1 1 2
A= → A=
9 7 0 9 7 0
1 1 2 2 4 8
Scambio di A (r, j) con A (c, j), per j=1, ...M.

- PASCAL-LIKE: liste concatenate

LEZIONE 13: REPEAT-UNTIL, WHILE E PROGRAMMAZIONE MODULARE


- PASCAL-LIKE: struttura repeat-until
Dato un array di nomi (un elenco) di lunghezza N determinare la posizione nell’array di un nome da cercare
Dati di input:
• N (lunghezza dell’elenco)
• Elenco (1), ..., Elenco(N) (l’elenco)
• NOME (nome da cercare)
Dati di output
• Pos (la posizione di NOME in Elenco)
IDEA: Esaminare uno alla volta gli elementi di Elenco, e confrontarli con il NOME
RICERCA SEQUENZIALE
Ci si deve arrestare quando:
• Si trova il NOME nell’Elenco oppure
• Si scorre tutto l’Elenco ma NOME non è presente (si assume Pos=0)
Esempio 1:
N = 5; NOME = ‘maria’; Elenco=(‘anna’, ‘ciro’, ‘bruno’, ‘maria’, ‘dario’)
Pos = 4 (i=4 iterazioni)
Esempio 2:
N = 5; NOME = giacomo; Elenco=(‘anna’, ‘ciro’, ‘bruno’, ‘maria’, ‘dario’)
Pos = 0 (i=5 iterazioni)
In pascal-like una tale struttura di iterazione è realizzata con la struttura
repeat-until
In generale:
• Vengono eseguite ripetutamente le Istruzioni comprese tra repeat e until.
• Ci si arresta quando la condizione posta alla fine della struttura risulta vera.
• In generale la condizione di arresto può essere la combinazione di più operazioni logiche
legate dagli operatori OR, AND e NOT.
• Le istruzioni non vengono più eseguite se la condizione risulta vera.

Algoritmo La struttura «repeat-until» è


Ricerca sequenziale in un array più flessibile e generale della
struttura «for-endfor».
Input:
• N (lunghezza dell’elenco) Una struttura «repeat-until» con
• Elenco (1), ..., Elenco(N) (l’elenco) una condizione di arresto solo sul
• NOME (nome da cercare) numero di passi è equivalente ad
una struttura «for-endfor».
Output
• Pos (la posizione di NOME in Elenco)

ALGORITMO: Massimo Comun Divisore tra A e B (non entrambi nulli)


IDEA: Metodo delle divisioni successive (o di Euclide)
1. Si DIVIDE il MAGGIORE di essi per il MINORE;
2. Se il RESTO della divisione è ZERO, il M.C.D. è il numero MINORE (ovvero il
divisore);
3. Se il RESTO della divisione è DIVERSO da ZERO si DIVIDE il numero
MINORE per tale RESTO.
4. Si continua così fino ad ottenere una divisione per ZERO. Il M.C.D. cercato è il DIVIDENDO dell'ultima divisione.

ALGORITMO: Massimo Comun Divisore tra A e B (non entrambi nulli)


È necessario
1. Effettuare la divisione (intera) tra A e B
2. Calcolare:
• Il quoziente Q
• Il resto R
3. Rinominare A e B per la successiva divisione
4. Ripetere finche’ B==0

DOMANDA
Cosa accade se il dato di input A=0?
Cosa accade se il dato di input B=0?

SOLUZIONE
Bisogna eseguire il test su B
PRIMA della divisione

- PASCAL-LIKE: struttura while-endwhile


In pascal-like esiste un’altra struttura di iterazione
while-endwhile.
In generale:
• Vengono eseguite ripetutamente le Istruzioni comprese tra while e endwhile;
• PRIMA valuta la condizione;
• DOPO esegue le istruzioni;
• Le istruzioni vengono eseguite se la condizione risulta VERA.
Scritto in questo modo l’algoritmo può essere utilizzato anche quando il dato di
input B=0!

- Come scegliere la struttura di iterazione?

La scelta dipende da
• Numero di iterazioni noto a priori;
• Necessità di verificare la condizione prima o dopo le istruzioni da
ripetere.
- PASCAL-LIKE: procedure
PROBLEMA:
• Siano dati due array di reali A e B rispettivamente di lunghezza N e M.
• Si vuole scrivere un algoritmo che calcoli il massimo MAX dei due valori medi MediaA e MediaB dei due array.
Esempio: N=8 M=10
A = (3; 6; 2; 9; 10; 1; 2; 5) --> MediaA = 4,75
B = (8; 3; 5; 2; 4; 9; 10; 0; 5; 7) --> MediaB = 5,3
MAX = 5,3
ALGORITMO:
1. Leggi N e l’array A
2. Leggi M e l’array B
3. Calcola la media MediaA dei valori di A
4. Calcola la media MediaB dei valori di B
5. Calcola il massimo MAX tra MediaA e mediaB
6. Stampa il valore di MAX
NOTA 1: Le istruzioni relative all’array B (blu) sono le stesse di quelle relative
all’array A (rosse): cambiano i dati su cui le istruzioni agiscono.
NOTA 2: Nel caso in cui il numero di array non sia 2 ma sia arbitrario,
contenuto di una variabile NUM data in input, non è possibile scrivere
l’algoritmo: quante volte scrivere il gruppo di istruzioni nell’algoritmo?
SOLUZIONE: trovare un modo per scrivere le istruzioni una sola volta e
riutilizzarle quando occorre.
• Si supponga di avere a disposizione un sottoalgoritmo MEDIA che ha come
• dati di input: un array e la sua lunghezza
• dati di output: la media degli elementi dell’array
• Si supponga inoltre che tale sottoalgoritmo MEDIA sia in grado di ricevere e
restituire dati ad un altro algoritmo.
• È possibile affidare il calcolo della media a tale sottoalgoritmo ogni volta che
occorre.
• Una procedura è un sottoalgoritmo richiamabile da un altro algoritmo in cui
l’input e l’output non avvengono mediante le istruzioni read e print, MA
scambiando dati con l’algoritmo chiamante
• Operativamente:
• rimozione delle istruzioni read e print;
• sostituzione dell’inizio dell’algoritmo con la testata della procedura
contenente i dati di input e output.

procedura nomeprocedura (in: dati di input; out: dati di output)


• La testata della procedura contiene:
• Il nome della procedura;
• I dati di input e di output da scambiare con l’algoritmo chiamante.
• La testata della procedura rappresenta l’unico canale di comunicazione con l’algoritmo chiamante.

• L’algoritmo chiamante utilizza la procedura attraverso il nome, scambiando con essa i


dati di input e di output
• Più precisamente:
1) Vengono scambiati i dati di input tra algoritmo chiamante e procedura;
2) L’algoritmo chiamante viene sospeso fino al completamento della procedura;
3) Al termine della procedura vengono scambiati i dati di output tra procedura e
algoritmo chiamante;
4) Viene ripresa l’esecuzione dell’algoritmo chiamante.
• La procedura può essere utilizzata più volte con dati diversi.
• Una procedura può richiamare a sua volta un’altra procedura.
• Chiamate innestate.
• L’ultima procedura ad iniziare sarà la prima a finire.
• L’algoritmo chiamante sarà l’ultimo a terminare.
• I dati nella testata della procedura sono chiamati argomenti
formali.
• I dati nella chiamata della procedura all’interno dell’algoritmo
chiamante sono chiamati argomenti attuali (o effettivi).
• La corrispondenza è PER POSIZIONE.
• È possibile utilizzare nomi diversi per gli argomenti formali
ed attuali.
• È necessario che gli argomenti che occupano la stessa posizione abbiano
lo stesso tipo.
• L’unico canale di comunicazione tra procedura ed algoritmo chiamante è
costituito dai dati presenti nella testata.
• Conseguenza: variabili che hanno lo stesso nome nei due algoritmi non
hanno niente in comune! (si noti la variabile “i”).
• Problema: cosa viene scambiato tra algoritmo chiamante e procedura al momento
della chiamata della procedura?

• PASSAGGIO PER INDIRIZZO


 Viene comunicata la posizione (indirizzo) in memoria delle variabili che
contengono i dati di input e output della procedura.
 La procedura opera direttamente sulle stesse variabili dell’algoritmo
chiamante.
 Nell’esempio, le variabili A, B e C dell’algoritmo chiamante prendono
temporaneamente i nomi X, Y e Z nella procedura.
 Utilizzato nel linguaggio Fortran.

• PASSAGGIO PER VALORE


 Viene comunicato il valore delle variabili che contengono i dati di input e output della procedura.
 La procedura utilizza delle variabili proprie, in cui copia i valori provenienti dall’algoritmo chiamante.
 Nell’esempio, le variabili A e B dell’algoritmo chiamante vengono copiate nelle variabili X e Y nella procedura,
mentre il valore di output Z viene copiato nella variabile C dell’algoritmo chiamante.
 Utilizzato nel linguaggio C (e derivati).

- Sviluppo modulare degli algoritmi


• Algoritmi complessi possono essere decomposti in procedure più semplici mediante
raffinamenti successivi.
• Vantaggi:
• Minore probabilità di errori;
• È possibile testare separatamente le procedure per verificarne il funzionamento;
• Possibilità di dividere il lavoro tra più persone.

ESEMPIO
Sviluppare un algoritmo somma per la somma di due vettori C = A + B
• Si procede individuando i passi fondamentali ed esprimendoli sotto forma di
procedure, individuandone gli argomenti di input e output.
• Le procedure leggivettore e stampavettore rispettivamente leggono e stampano un
vettore.

• leggivettore
• Dati di input: nessuno
• Dati di output: un array e la sua lunghezza
• stampavettore
• Dati di input: un array e la sua lunghezza
• Dati di output: nessuno

• La procedura sommavettori esegue la somma di due vettori


• Dati di input:
• A e B (due vettori)
• N (lunghezza dei vettori)
• Dati di output
• C (Il vettore somma)
• C’è un’altra procedura che può essere innestata
Le procedure si usano come «scatole nere» per sviluppare algoritmi più
complessi.

Potrebbero piacerti anche