Politecnico di Milano Facoltà di Ingegneria Industriale INFORMATICA B Esempio di seconda prova in itinere A.A. 2008-2009 Esercizio 1 Si vuole considerare la traiettoria percorsa da un oggetto immaginario nel tempo. L oggetto di muove nel piano x,y secondo le seguenti leggi: x=2cos(3t) y=(t/2) 2 Si scrivano in linguaggio MATLAB/Octave i comandi necessari per: a) tracciare il grafico della traiettoria percorsa dal corpo nel piano x,y nei primi 5 secondi. tracciare la posizione del corpo nel piano x,y al variare del tempo t nell intervallo [0,5s]. a) t=0:0.05:5; x=2*cos(3*t); y=(t/2).^2; plot(x,y); plot3(x,y,t); Esercizio 2 Data la seguente funzione: function z=mistero(x) if x>=1 z=mod(x,2)+10*mistero(floor(x/2)); z=0; a) Quanto vale mistero(7) e mistero(8)? Cosa calcola in generale la funzione mistero(x)? La figura qui sopra mostra come avvengono le chiamate ricorsive. In particolare viene mostrata in ogni blocco l immagine del record di attivazione associata ad ogni chiamata. a) mistero(7)=111, mistero(8)=1000 mistero(x) calcola un valore numerico in base 10 la cui sequenza di cifre può essere interpretata come rappresentazione del numero naturale x nel sistema binario.
Esercizio 3 Data una generica matrice A di dimensioni NxM contenente numeri interi, si scrivano in linguaggio MATLAB/Octave i comandi necessari per eseguire le seguenti operazioni: a) assegnare alla variabile u i valori della prima riga della matrice. cambiare il segno di tutti i numeri dispari presenti nella matrice. c) assegnare alla variabile v gli indici delle colonne la cui somma degli elementi è inferiore a 10. a) [r, c] = size(a); u=a(1,1:c) oppure u=a(1,:) t=(mod(a,2)~=0); A(t)=-A(t) mod(a,2) ritorna una matrice delle stesse dimensioni di A contenente 1 negli elementi corrispondenti a quelli dispari, 0 in quelli corrispondenti a quelli pari. mod(a,2)~=0 genera una matrice logica che contiene il valore vero negli elementi dispari, falso in quelli pari. Questa matrice logica chiamata t viene poi usata per selezionare gli elementi di A di cui si vuole cambiare il segno. c) v=find(sum(a)<10) oppure [r, c] = size(a); col = zeros(1, c); for icolonna=1:c for iriga=1:r col(icolonna)=a(iriga, icolonna)+col(icolonna); v = find(col<10); Esercizio 4 Faco uso delle funzioni di ordine superiore map e acc presentate a lezione si scriva una funzione denominata presente(x,v), dove x è un valore e v un vettore. La funzione ritorna un valore booleano che è vero se e solo se è vera la seguente condizione: x==v(1) OR x==v(2) OR... OR x==v(length(v)) Le funzioni map e acc sono riportate di seguito: function [vout]=map(f, vin) for i=1:length(vin) vout(i)=f(vin(i)); function [x]=acc(f, a, u) x=u; for i=1:length(a) x=f(x, a(i)); function [p]=presente(x,v) eqx=@(a)a==x; vp=map(eqx,v); OR=@(h,k)h k; p=acc(or,vp,0); Simulazione (si ottiene toglio il ; dopo l istruzione vp=map(eqx,v);) >> v=[1 2 3 4] >> presente(3,v) vp = 0 0 1 0 ans = 1
Esercizio 5 Si consideri il seguente numero X codificato secondo lo standard virgola mobile IEEE a precisione singola: X=SEGNO ESPONENTE MANTISSA=1 10101010 00000000000000000000000 a) Quanto vale X in base 10? Se si cambiasse in 1 il bit più significativo della mantissa di X, quanto varrebbe tale numero in base 10? c) Rappresentare secondo lo standard virgola mobile IEEE il numero Z=2X. a) exp_eccesso_k=2 7 +2 5 +2 3 +2 1 =128+32+8+2=170 k=2 bit_esponente-1-1=2 7-1=127 X in base 10 = (-1) bit_segno *2 exp_eccesso_k-k *1.Mantissa = -1*2 43 *1 = -2 43 nuova mantissa di X=10000000000000000000000 mantissa in base 10=2-1 =0.5 Ricalcoliamo X: (-1) bit_segno *2 exp_eccesso_k-k *1.Mantissa = -1*2 43 *1.5 = -1.5*2 43 c) per calcolare il doppio di un numero devo semplicemente incrementare l esponente di 1, per cui il numero Z e : Z=1 10101011 00000000000000000000000 Esercizio 6 Un sistema dispone di 8 Kbyte di memoria fisica indirizzabile; inoltre è dotato di memoria virtuale con paginazione caratterizzata dai seguenti parametri: l indirizzo virtuale della memoria è di 15 bit e le pagine sono di 256 byte. a) Qual è la dimensione della memoria virtuale indirizzabile? Definire la struttura dell indirizzo virtuale e di quello fisico indicando la lunghezza dei campi che li costituiscono. Dimensione memoria fisica = 8Kbyte = 2 3 *2 10 byte = 2 13 byte Dimensione pagine = 256 byte = 2 8 byte a) la memoria virtuale indirizzabile è pari a 32 Kbyte (2 15 byte) Indirizzo Virtuale: 15 bit = NPV+offset [ come da testo ] offset: 8 bit [ Calcolato come log 2 (dimensione pagine)=log 2 (2 8 )=8 bit ] NPV: 7 bit [ Calcolato come bit_indirizzo_virtuale - offset = 15-8=7 ] Indirizzo Fisico: 13 bit = NPF+offset [ Calcolato come log 2 (dimens memoria fisica)= log 2 (2 13 )=13 ] NPF: 5 bit [ Calcolato come bit_indirizzo_virtuale - offset = 13-8=5 ] offset: 8 bit [ È sempre uguale all offset della memoria virtuale ] Esercizio 7 Si consideri una memoria cache dalle seguenti caratteristiche: Hit Rate: HR = 80% Hit Time: HT = 10ns Miss Penalty: MP = 460ns Il tempo medio di accesso alla memoria si può calcolare con la formula: HR*HT+(1-HR)*MP a) Qual è il tempo medio di accesso alla memoria in questo caso? Per poter dimezzare il tempo medio di accesso alla memoria, quale dovrebbe essere l hit rate minimo della cache? a) tempo medio di accesso = HR*HT+(1-HR)*MP = 0.80*10ns+0.20*460ns = 100ns tempo medio di accesso desiderato = 50ns 50=HR*10+(1-HR)*460 50=10HR-460HR+460 450HR=410 HR=41/45 (=91,1%)
Esercizio 8 Una versione semplificata del gioco della vita (Game of Life) si svolge su una griglia di caselle rappresentate con una matrice a 2 dimensioni. Ogni casella puo essere in 2 stati: viva (valore 1) o morta (valore 0). L intorno di una casella è definito come l insieme dalle sue caselle circostanti. Lo stato di tutte le caselle evolve a intervalli di tempo discreti: lo stato di una casella all istante successivo dipe dallo stato del suo intorno all istante precedente, come da seguenti regole: Una casella morta diventa viva se nell istante precedente ha esattamente 3 caselle vive nel suo intorno. Una casella viva muore se nell istante precedente ha meno di 2 caselle vive nel suo intorno (morte per isolamento) o più di 3 caselle vive nel suo intorno (morte per sovraffollamento). a) Si scriva una funzione in linguaggio MATLAB/Octave avente come parametro di ingresso la griglia di caselle in un certo istante e come parametro di uscita la griglia di caselle nell istante successivo. Si supponga che esista già una funzione conta_caselle_vive_vicine(griglia) che ritorna una matrice delle stesse dimensioni della griglia, il cui valore di ogni elemento è uguale al numero di caselle vive attorno alla casella corrispondente della griglia. Si scriva una funzione che salvi la griglia di caselle in un file di testo passato come parametro. c) (facoltativo) Si implementi la funzione conta_caselle_vive_vicine(griglia) descritta sopra. a) (versione risolta con vettori logici) function [griglia_risultato]=gioco_della_vita(griglia) griglia_risultato=griglia; vicini_vivi=conta_caselle_vive_vicine(griglia); griglia_risultato(griglia==1&(vicini_vivi<2 vicini_vivi>3))=0; griglia_risultato(griglia==0&vicini_vivi==3)=1; a) (versione risolta con cicli for) function [griglia_risultato]=gioco_della_vita(griglia) griglia_risultato=griglia; vicini_vivi=conta_caselle_vive_vicine(griglia); if griglia(ii,jj)==1 if vicini_vivi(ii,jj)<2 vicini_vivi(ii,jj)>3 griglia_risultato(ii,jj)=0; if vicini_vivi(ii,jj)==3 griglia_risultato(ii,jj)=1; function [count]=scrivi_griglia(griglia,nomefile) fid=fopen(nomefile,'w'); count=0; if fid>0 count=count+fprintf(fid,'%d ',griglia(ii,jj)); count=count+fprintf(fid,'\n'); flose(fid); disp('errore di accesso al file');
c) (versione risolta usando le sottomatrici) function [griglia_conteggi]=conta_caselle_vive_vicine(griglia) riga_sup=max([ii-1 1]); % calcolo riga più alta dell intorno riga_inf=min([ii+1 num_righe]); % calcolo riga più bassa dell intorno colonna_sx=max([jj-1 1]); % calcolo colonna più a sinistra dell intorno colonna_dx=min([jj+1 num_colonne]); % calcolo colonna più a destra % dell intorno % calcolo la sottomatrice della griglia corrispondente all'intorno intorno=griglia(riga_sup:riga_inf,colonna_sx:colonna_dx); % calcolo la somma degli elementi vivi dell intorno. % Si noti che il precedente intorno include anche l'elemento % centrale (che non dovrebbe far parte dell'intorno), % per cui lo sottraiamo dalla somma. griglia_conteggi(ii,jj)=sum(sum(intorno))-griglia(ii,jj); c) (versione risolta usando costrutti if multipli) function [griglia_conteggi]=conta_caselle_vive_vicine(griglia) count=0; % eseguo dei controlli per non accedere a caselle inesistenti if ii>1&&jj>1 % casella in alto a sinistra count=count+griglia(ii-1,jj-1); if ii>1&&jj<num_colonne % casella in alto a destra count=count+griglia(ii-1,jj+1); if ii<num_righe&&jj>1 % casella in basso a sinistra count=count+griglia(ii+1,jj-1); if ii<num_righe&&jj<num_colonne % casella in basso a destra count=count+griglia(ii+1,jj+1); if ii>1 % casella in alto count=count+griglia(ii-1,jj); if ii<num_righe % casella in basso count=count+griglia(ii+1,jj); if jj>1 % casella a sinistra count=count+griglia(ii,jj-1); if jj<num_colonne % casella a destra count=count+griglia(ii,jj+1); griglia_conteggi(ii,jj)=count;