Soluzione esercizio Soluzione esercizio • Caso n = 0 . i = 0, quindi il predicato “mentre i ≠ 0 …” è falso: il ciclo non viene eseguito. • Caso n < 0 . se a < b il ciclo non termina: a diminuisce e quindi rimane minore di b se a = b il ciclo non termina: entrambi crescono di 1 se a > b il ciclo termina: continua diventa falso. Soluzione esercizio Soluzione esercizio • Caso n > 0 . • Caso a < b . Viene eseguita l’istruzione a ← a-1, quindi è ancora a < b; il ciclo termina quando i = n; il numero di operazioni è: 2ta + (n+1) tp + nta + ntc + nta ⇒ c·n • Caso a > b . Viene eseguita l’istruzione continua ← falso, quindi il ciclo termina; il numero di operazioni è: 2ta + tp + ta + tc + tc + ta + tp ⇒ costante continua← i← i← a<b a← b non varia, a diventa a-n continua← i← a<b a=b continua← i← b non varia, a non varia Soluzione esercizio • Caso a = b . Vengono eseguite le istruzioni a←a+1 e b←b+1; il ciclo interno viene eseguito n volte e il ciclo esterno termina quando i = n; il numero di operazioni è: 2ta + (n+1) tp + nta + ntc + n tc + n(n+1) tp+ continua← i← a<b Numeri frazionari periodici a=b i← + 2 n2ta ⇒ c·n2 a← b← a diventa a + n2 , b diventa b + n2 1 Numeri frazionari periodici Numeri frazionari periodici • Abbiamo visto che 0.110 = 0.0 00112 • Consideriamo un numero razionale: p/q con p e q naturali e primi fra loro e q≠0 Eseguendo la divisione p:q=… si può ottenere una rappresentazione finita oppure infinita e periodica della parte frazionaria. a) Se i fattori primi di q sono solo quelli della base, allora la rappresentazione è finita. b) Se tra i fattori primi di q ci sono fattori diversi dai fattori della base, allora la rappresentazione è infinita e periodica. • Vediamo per la base b = 10 = 2··5 • Caso a) q = 2k · 5h ; sia n = max(h,k); allora si può scrivere p m = q 10n con m naturale m = cs cs-1 …. c1 c0 Numeri frazionari periodici Numeri frazionari periodici • Spostando la virgola di n posti verso sinistra a partire da c0 si trova la rappresentazione finita, perché finito è il numero di cifre di m. • Esempio. • Caso b) q = ak · bh con a e b anche diversi da 2 e 5; ne segue che non si potrà scrivere q come potenza di 10. Quando si esegue la divisione: p = q k1 + k2 0 ≤ k2 < q se le cifre di p sono terminate si “abbassa lo 0” e si prosegue con la divisione. Il resto k2, variando in un intervallo limitato, ad un certo punto si ripete: si ha pertanto il periodo. 31 / 20 = 31 / (22 · 5 ) = (31 · 5)/ (22 · 52 ) = = 155 / 102 = 1.55 7 / 25 = 7 / 52 = (7 · 22)/ (22 · 52 ) = = 28 / 102 = 0.28 Numeri frazionari periodici • Esempio. 10 / 3 5/7 10 : 3 = 3. 3 3 3 ….. 10 1 1 ….. periodo 5 : 7 = 0.714285 714…… 50 10 30 20 60 40 5 ….. periodo Numeri frazionari periodici • Un numero periodico in base 10 (ci sono fattori diversi da 2 e 5) è anche periodico in base 2. • Un numero non periodico in base 10 può essere periodico in base 2 (ad esempio 0.1, 0.4). • I numeri irrazionali, i reali che non si possono scrivere come quoziente di due interi, hanno una rappresentazione infinita e non periodica. 2 Passaggi 2 2n Passaggi • 2n →2 : si espandono le cifre della base 2n in gruppi di n bit 16 = 24 → 2 • 2 →2n : si raggruppano le cifre della base 2 n a n 2 = 2 → 24 • Esempio. A91.2 16 = ? 2 = ? 8 A 9 1 . 2 1010 1001 0001 . 0010 5 2 2 1 . 1 base 16 2 2n • Esempio. 2E0.FC 16 = ? 2 = ? 8 2 E 0 . F C 0010 1110 0000 . 1111 1100 1 3 4 0 . 7 7 base 16 base 2 base 8 base 2 base 8 Operazioni in base 2 Operazioni in base 2 • Addizione. 0+0=0 1+0=0+1= 1 1 + 1 = 1(riporto) 0 Esempio. 1 5+ 5 21 0 Operazioni in base 2 • Sottrazione. 0-0=0 1-0=1 0 - 1 = 1(prestito)0 - 1 = 1 Esempio. 1 1 1 1+ 1 0 1 1 0 11 10 10 Operazioni in base 2 • Moltiplicazione. 0×0=0 1×0=0×1=0 1 × 1 =1 con 1 si ricopia il numero con 0 spostamento a sinistra, poi si somma Esempio. 21 0 5 1 5 11 01 11 01 0 0 1 0 1 0 1 1 1 1 3 × 5 = 15 1 1× × 101 11 11-1111 3 Operazioni in base 2 • Divisione. se il divisore ci sta, si mette 1; altrimenti 0 Esempio. Rappresentazione degli interi 1111 : 11= 101 11 011 11 0 15 : 3 = 5 Rappresentazione degli interi • Si hanno i seguenti tipi di dato byte, short, int, long corrispondenti ad un’occupazione di memoria rispettivamente di n =8, 16, 32, 64 bit Rappresentazione degli interi • Rappresentazione di x ≥ 0 • x=0 0 00000…00000 r(x) = 0 segno numero 0 per lo zero e i positivi 1 per i negativi segno [ -2n-1 , 2n-1-1] Rappresentazione degli interi • Rappresentazione dell’intervallo dei numeri negativi. Si rappresenta l’opposto di x > 0: -x < 0 Si definisce r(-x) in modo tale che sia: r(x) + r(-x) = 2n = 1 000…000 2 n Si dice che l’opposto di x è rappresentato in “complemento a 2”. • Ci sono state anche altre scelte (complemento a 1); oggi è la rappresentazione degli interi in uso nella maggior parte dei calcolatori. tutti i bit 0 0 < x < 2n-1 -1 • x>0 r(x) si ottiene dividendo x per 2 e prendendo i resti: r(x) = ck ck-1… c1 c0 2 n-1-1 0 1111111 … 1111 …... …… 1 0 0000 ……… 001 0 0 0000……..00000 0 00…ck ck-1 …c1 c0 Rappresentazione degli interi • Vediamo un esempio con n=3 bit: [ -23-1, 23-1-1]= 3 0 11 = [ -22 , 22 -1] 2 1 0 -1 -2 -3 -4 0 0 0 1 1 1 1 10 01 00 11 10 01 00 r(-1) = 2n – r(1) = 1000 – 001 = = 111 r(-2) = 2n – r(2) = 1000 – 010 = = 110 4 Rappresentazione degli interi • Regola. • Si calcola r(x) e poi: - si invertono tutti i bit e si aggiunge 1 - si invertono tutti i bit tranne gli zero a destra e il primo 1 a destra. • Infatti si sottrae da 100…00: finché si sottrae 0 da 0 il bit è 0 (quindi è uguale); quando si sottrae il primo 1 da 0, scatta il prestito 10-1=1 (il bit è uguale); con il prestito (verso sinistra) il bit 0 diventa 1 (infatti, per poter fare 10 il bit 1 viene sottratto dal bit 0 subito a sinistra) e nella sottrazione da 1 il bit si inverte. Il bit del segno è trattato come gli altri bit. Rappresentazione degli interi • Questa regola è facile da realizzare. • In tale modo si fanno solo somme: - somma - differenza: si somma l’opposto; invece di a-b si fa r(a) + r(-b) - moltiplicazione: si somma - divisione: si fanno differenze e quindi somme Rappresentazione degli interi Rappresentazione degli interi • Modularità degli interi e overflow. • Cosa accade se si esce dall’intervallo di rappresentazione? Il “trabocco” (overflow) è un errore logico non segnalato: il numero viene calcolato e si ripropone un valore dell’intervallo, come se l'intervallo si ripetesse. • Quando si somma un numero e il suo opposto la somma è una sequenza di bit tutti nulli e il bit 1 che “trabocca” dagli n bit si trascura: ad esempio con n=8 r(1) + r(-1) = 00000001 + 11111111 = 2n = = 100000000 il bit 1 si trascura nella somma. • Quando sommiamo 127 + 1 = 128 (non appartiene all’intervallo), abbiamo: r(127) + r(1) = 01111111 + 00000001 = = 10000000 = r(-128) la somma di due positivi è un negativo !!!! overflow. • Esempio. 2 + 2 = 4 (fuori dall’intervallo, n=3) 010 + 010 = 100 = r(-4) Rappresentazione degli interi Rappresentazione degli interi • Si può dimostrare che: • nell’addizione di due numeri in complemento a due si ha una situazione di overflow se e solo se: • si ha un riporto tra la colonna (n-1)-esima e la colonna n-esima e non si ha un riporto tra la colonna n-esima e la colonna (n+1)-esima (esempio: r(127) + r(1)) • non si ha un riporto tra la colonna (n-1)-esima e la colonna n-esima e si ha un riporto tra la colonna nesima e la colonna (n+1)-esima • Il verificarsi di un overflow deriva dal fatto che si è “usciti” dall’intervallo di rappresentazione: [minint, maxint]. • Non c’è segnalazione di errore perché viene costruito un “numero valido” ossia un numero che “sta” nella rappresentazione: è come se l’intervallo minint si ripetesse e si maxint …. parla di modularità …. della rappresentazione minint degli interi. maxint 5 Rappresentazione degli interi • La divisione per 0 è un errore. • Se si effettua una divisione a / b con a e b variabili intere e b=0 si genera un’eccezione che interrompe l’esecuzione del programma: ArithmeticException Esponente intero dei reali Esponente intero dei reali Esponente intero dei reali • I reali sono rappresentati con mantissa ed esponente. Tale esponente è intero. • La rappresentazione per l’esponente intero segue una diversa regola: l’esponente e è rappresentato in traslazione, ossia con eccesso. • L'esponente e appartiene all'intervallo [0, 2s -1] (o [0, 2s -1-1], eccesso pari) dove s è il numero di bit della sua rappresentazione. • I numeri rappresentati sono (n=3 bit): 2n-1 pari 1 1 1 1 0 0 0 0 max eccesso k = 2n-1 e -1 dispari r(e) = e + k min 11 10 01 00 11 10 01 00 [min, max] corrispondono a [-4, 3] se k è pari [-3, 4] se k è dispari Esponente intero dei reali Esponente intero dei reali • Negli anni ci sono state varie scelte per la rappresentazione dei reali: ad esempio per i reali in semplice precisione: • Nel caso dei float (32 bit) l’eccesso k = 27 -1 = 127. • Il vero intervallo è [0, 255] che corrisponde all’intervallo (non traslato) [-127, 128]. • In binario: • base 16, esponente in 7 bit, eccesso pari 64 (sui grossi calcolatori); con l’eccesso pari vale ancora la regola che r(x) + r(-x) = 2n. • base 2, esponente in 8 bit, eccesso dispari. • Lo standard IEEE (Institute for Electrical and Electronics Engeneering) nel 1985 ha scelto per i Personal Computer (ora in uso nella maggior parte dei calcolatori): base 2, eccesso dispari. 255 11111111 128 … 1 0 …. 00000001 00000000 ... -126 -127 6 Rappresentazione dei reali Rappresentazione dei reali • I numeri reali sono rappresentati in virgola mobile: floating point. • Ogni numero reale a può essere scritto nella forma a = p Nq con p numero reale, N (N>1) base della rappresentazione, q numero intero. • Sia a ≠ 0, se si considera 1/ N ≤ |p| < 1 • la rappresentazione è unica. Rappresentazione dei reali Rappresentazione dei reali • Con N=10 si ha: 1/ 10 ≤ |p| < 1 , pertanto |p| = 0.c1 c2 … con c1 ≠ 0 . • La rappresentazione si dice normalizzata e il numero, fissata la base, è individuato dalla coppia (p, q). Il numero reale p si chiama mantissa, il numero intero q si chiama esponente o caratteristica. • Nella rappresentazione dei reali nel calcolatore, la mantissa ha un numero t, finito e fissato a priori, di cifre: t=23, t=52. • Le mantisse con più di t cifre devono essere approssimate. • Si hanno due modi per approssimare un numero: il troncamento e l’arrotondamento: • troncamento: si escludono le cifre dalla t+1 in poi; • arrotondamento: si aggiunge (1/2)N-t e si tronca. • Esempio. N=10, t=6; (1/2)N-t = 0.5 × 10-6 = 0.0000005 0.123456789 + 0.0000005 = 0.123457 289 Rappresentazione dei reali Rappresentazione dei reali • Consideriamo due mantisse consecutive p1 e p2, la loro distanza è N-t (esempio: 0.123456, 0.123457; 0.131119 0.131120). Sia p una mantissa da rappresentare e sia p la sua rappresentazione; si ha • Sia a un numero da rappresentare e a la sua rappresentazione. Si hanno due tipi di errore: • Errore assoluto |a-a| N-t troncamento (1 /2)N-t arrotondamento |p –p | ≤ • L’errore di arrotondamento è la metà di quello per troncamento. • è la distanza di a dal suo rappresentante a. • Errore relativo |a-a| | a | • è l’errore che si commette utilizzando il rappresentante indipendentemente dalla grandezza del numero 7 Rappresentazione dei reali • Per l’errore assoluto si ha: |a – a | = |pNq – p Nq| = |p – p |Nq da cui: |a – a | ≤ N-t+q nel troncamento |a – a | ≤ (1/2) N-t+q nell’arrotondamento • I numeri reali sono rappresentati in arrotondamento. • Per l’errore relativo si ha: N1-t | (a – a ) / a | ≤ Rappresentazione dei reali • Un numero reale è rappresentato: • in modulo e segno: si rappresenta il valore assoluto e si aggiunge il segno: 0 per i positivi, 1 negativi • riferito alla base 2 • con eccesso (bias) dispari • con bit nascosto (hidden bit). a = m × 2e a≠0 m = 1. c1 c2 c3 …. normalizzata (1 /2)N1-t Rappresentazione dei reali • Float 32 bit: 1(segno) + 8(esponente) + 23(mantissa) • L’esponente varia nell’intervallo [-127, 128] = [-27-1, 27] traslato [0, 255] 128 255 111111111 … … …. -127 0 000000000 Rappresentazione dei reali • Lo zero è rappresentato con un sequenza di bit tutti nulli: zero = 0 00000000 00000…….0000 • I numeri diversi da zero sono rappresentati con una mantissa normalizzata: 1. c1 c2 … • La mantissa più piccola è 1.0000... , la mantissa più grande è 1.1111..... • Per via della normalizzazione, il bit 1 può essere “sottinteso” e non viene memorizzato: bit nascosto. Rappresentazione dei reali Rappresentazione dei reali • Gli estremi dell'intervallo per l'esponente sono utilizzati per rappresentare situazioni particolari: • -127 è l'esponente dello zero, se i bit successivi sono tutti nulli, altrimenti si rappresenta un numero non normalizzato; • 128 rappresenta infinito (Infinity) se i bit successivi sono nulli, altrimenti si rappresenta un numero non valido: NaN (Not a Number) • Diversamente dagli interi, nei reali la divisione per 0 produce “infinito”: 1. / 0 Infinity • Invece se anche il numeratore è 0 si ottiene un numero non valido: 0. / 0 NaN Sono ovviamente errori logici ma il programma non interrompe l’esecuzione. 8 Rappresentazione dei reali • I valori estremi dei reali, in semplice precisione, rappresentabili sono: • minimo reale 1.0000..... × 2-126 ~ 10-38 • massimo reale 1.1111..... × 2127 ~ 1038 • Lo standard IEEE permette anche la rappresentazione non normalizzata della mantissa (non presente però su tutti i calcolatori) 0.000....1, che porta ad un minimo reale dell’ordine di 10 -45. Rappresentazione dei reali • Possibile perdita di precisione nella somma. • Può accadere che si abbia, con b ≠ 0 a+b=a se b ≤ a / Nt dove N è la base e t il numero di cifre della mantissa. Significa che b è “piccolo rispetto ad” a. • Esempio. Consideriamo N=10, t=6 a = 334156 = 0.334156 × 106 b = 0.000012 = 0.12 × 10-4 10-4 ≤ 106 / 106 = 100 Rappresentazione dei reali Rappresentazione dei reali • Per eseguire la somma si devono incolonnare i due numeri (si portano allo stesso esponente): 334156. + 0.000012 = 334156.000012 • Avendo a disposizione 6 cifre la somma sarà: 334156. • Poiché con t = 23 cifre di mantissa si rappresentano 6 decimali esatti e con t = 52 bit di mantissa si rappresentano circa 15 decimali esatti, il calcolo precedente sarebbe esatto in doppia precisione. • Cosa accade se si fa: a+b–a? a + b – a = (a + b) – a = a – a = 0 Errore, perché b è “piccolo rispetto ad a” ma non è piccolo rispetto a 0. • Per non perdere precisione nei calcoli sommando numeri di diversa grandezza, si può ricorrere a formule alternative: a+b–a=a–a+b=0+b=b Rappresentazione dei reali Rappresentazione dei reali • Abbiamo detto che: t= 23 cifre di mantissa corrispondono a 6 decimali 127 38 2 ~ 10 1024 = 210 ~ 103 • Quale relazione lega le potenze di base 10 a quelle di base 2? 2B ~ 10D D D = log10 10 ~ log10 2B = B ×log102 ~ B × 0.3 float: 2127 ~ 10127× 0.3 = 1038.1 2-126 ~ 10-126× 0.3 = 10-37.8 double: 21023 ~ 101023× 0.3 = 10306.9 2-1022 ~ 10-1022× 0.3 = 10-306.6 9 Rappresentazione dei reali • Analogamente, possiamo stimare il numero di cifre della mantissa: b=2 1.c1 c2 … ct ct è moltiplicata per 2-t b=10 0.k1 k2 ….kn kn è moltiplicata per 10-n quindi: 2-t ~ 10-n • float: t=23 2-23 ~ 10-23 × 0.3 = 10-6.9 6,7 decimali esatti • double: t=52 2-52 ~ 10-52 × 0.3 = 10-15.6 15, 16 decimali esatti Rappresentazione dei reali 0.14 × 2 0.28 0.56 1.12 0.24 0.48 0.96 1.92 1.84 1.68 1.36 0.72 1.44 0.88 1.76 1.52 1.04 esponente 135 135 2 67 33 16 8 4 2 1 0 1 1 1 0 0 0 0 1 s e 1 bit 0 10000111 01000110 00100011110100 Rappresentazione dei reali esponente 132 0.15 × 2 0.30 0.6 1.2 0.4 0.8 1.6 1.2 0.4 0.8 …. 132 2 66 33 16 8 4 2 1 0 0 0 1 0 0 0 0 1 s e 1 bit 1 10000100 10010 001001100110011001 Rappresentazione dei reali • Esercizio. Scrivere 326.1410 come float. • Soluzione. • Scriviamo il numero in binario: PI.PF 326 2 163 81 40 20 10 5 2 1 0 0 1 1 0 0 0 1 0 1 326.10 = 101000110.2 = = 1. 010001102 × 28 l’esponente da memorizzare è: 8 + 127 = 135 Rappresentazione dei reali • Esercizio. Scrivere -50.1510 come float. • Soluzione. • Scriviamo il numero in binario: PI.PF 50 2 25 12 6 3 1 0 0 1 0 0 1 1 50.10 = 110010.2 = = 1. 100102 × 25 l’esponente da memorizzare è: 5 + 127 = 132 Rappresentazione dei reali • Esercizio. • Scrivere come float il numero: -250.27 Soluzione. 1 10000110 1111010 0100010100011110 • Scrivere come float il numero: 0.04 Soluzione. 0 01111010 01000111101011100001010 10 Rappresentazione dei reali • Esercizio. Scrivere in binario -480 1) sequenza di caratteri ASCII 2) intero 3) reale • Soluzione. 1) stringa “-480” nel codice ASCII - al posto 4 8 0 45 52 56 48 come: 00101101 00110100 00111000 00110000 Rappresentazione dei reali 2) intero -480; si calcola complemento 480 2 240 0 120 0 60 0 30 0 15 0 7 1 3 1 1 1 0 1 r(480) e poi si fa il 48010 = 1111000002 0 00000 . . . . 0000111100000 r(480) 1 11111 . . . . 1111000100000 r(-480) 00101101 00110100 00111000 00110000 Rappresentazione dei reali 3) reale 480. segno – quindi il bit è 1 480. = 111100000. × 20 = 1.11100000 × 28 esponente 8+127 = 13510 = 100001112 1 bit nascosto 1 10000111 1110000 . . . . 00 . . • La sequenza di bit dipende dal tipo di dato che si vuole memorizzare. Rappresentazione dei reali • Esercizio. Si consideri il numero riferito alla base 16 3 D 1 0 0 0 0 0 16 e lo si interpreti come 1) numero intero 2) numero reale • Soluzione. Consideriamo il numero in binario: 0011 1101 0001 0000 0000 0000 0000 0000 Rappresentazione dei reali Rappresentazione dei reali 1) intero; il primo bit è 0 quindi il numero è positivo 2) reale; il primo bit è il segno, i successivi 8 bit sono l’esponente, e poi seguono i bit della mantissa, e si deve considerare il bit nascosto: e = 0111 1010 2 = 7 A 16 = 7 ×161 + 10 × 160 = = 112 + 10 = 122 dobbiamo ritrovare il “vero esponente”: 122 – 127 = -5 La mantissa è: m = 1.001000 . . . × 2-5 3D10000016 = 3 ×167 + 13 ×166 + 1× ×165 + 0 = = 3 × 268435356 + 13 ×16777216 + + 1048576 = = 1024458752 ∈ [ -231, 231 -1] 11 Rappresentazione dei reali m = 0.00001001000 . . . × 20 = 2-5 + 2-8 = 1 /32 + 1 / 256 = 0.03125 + 0.00390625 = 0.03515625 Eccezioni • Ogni sequenza di bit ha una diversa interpretazione a seconda del tipo di dato memorizzato. Eccezioni Eccezioni • Quando si progetta un algoritmo che risolve una classe di problemi si devono sempre prevedere dei casi limite: scelte di dati che servono a testare l’algoritmo (casi di prova). • Esistono però anche delle situazioni che sono esterne al problema. Cosa succede se i dati in ingresso non sono esatti? Se si introduce una stringa al posto di un numero? Se c’è un errore nel disco o cade la linea o altro per cui la lettura dei dati non va a buon fine? Sono situazioni eccezionali. • Le situazioni eccezionali possono però dipendere anche da un cattivo uso dell’algoritmo. • Esempio. Eccezioni Eccezioni • Gli errori vanno previsti e gestiti. • In Java c’è la possibilità di inserire dei costrutti che permettono di “catturare” l’eccezione e di proporre una alternativa. • Se però non sappiamo cosa proporre come soluzione all’errore, è preferibile lasciare andare l’eccezione: il metodo si interrompe e il “gestore competente” manderà un messaggio. • Se un utente del nostro programma inserisce un dato errato, come una stringa al posto di un numero, il metodo di lettura “lancia” un’eccezione; noi possiamo decidere che vogliamo poter permettere di inserire nuovamente il dato invece di interrompere il programma: l’eccezione viene catturata nel costrutto e gestita in maniera opportuna. • Possiamo anche decidere di lanciare un’eccezione se l’utente esegue una operazione illecita: riteniamo che l’errore sia grave e che il programma si debba interrompere. • considerare un saldo negativo: non si può prelevare denaro se i soldi non sono sufficienti • non si può calcolare il perimetro di un triangolo se i tre numeri a, b, c non sono positivi. • Si può scegliere di eseguire un controllo, oppure di lanciare un’eccezione. (par. 11.2, 11.3, 11.4, 11.6) 12 Eccezioni Eccezioni • Le eccezioni sono oggetti e sono descritte in classi. • C’è un gerarchia nella classi e all’interno di essa si distinguono due categorie: le eccezioni controllate (a controllo obbligatorio) e quelle non controllate (Capitolo 11 figura 2). • Le eccezioni controllate si chiamano così perché il compilatore verifica: • che nell’intestazione del metodo in cui appare un’istruzione che può generare questa eccezione ci sia la clausola: throws Classeccezione • oppure che tale eccezione sia gestita. • Solitamente le eccezioni controllate riguardano lo scambio di informazioni tra il programma e l’esterno e solitamente si lasciano al gestore competente che: Eccezioni Eccezioni • Le eccezioni controllate descrivono problemi che solitamente il programmatore non può evitare: per questo motivo il compilatore verifica che siano gestite. Tra queste eccezioni ci sono: • IOException: che può essere lanciata dal metodo di lettura readLine o read • FileNotFoundException: che può essere lanciata per la costruzione un oggetto di tipo FileReader • Cosa accade se l’input non risulta possibile perché: • proviene da un file su disco, il disco può essere difettoso • proviene da una connessione di rete, la cui connessione può interrompersi durante la lettura • non c’è il file che si vuole leggere? • Le eccezioni che non sono a controllo obbligatorio sono le RuntimeException: queste rappresentano errori del programma o errori che il programma può gestire. Poiché non sono controllate dal compilatore non è necessario inserire la clausola throws Classeccezione. Tra queste: • NullpointerException: utilizzo di un riferimento null • IndexOutOfBoundsException: indice al di fuori dei limiti di un array. • L’eccezione può essere evitata utilizzando dei controlli, ossia delle precondizioni introdotte con enunciati if(condizione), oppure può essere catturata e gestita in un costrutto try-catch. Eccezioni Eccezioni • Sintassi per le eccezioni controllate. accesso tiporestituito nomemetodo (tipo parametro, …) throws Classeccezione { //corpo del metodo } • Se nel metodo ci sono più istruzioni che possono generare eccezioni controllate, nella clausola throws si aggiunge l’elenco delle eccezioni separate da virgola. • interrompe l’esecuzione del metodo che ha sollevato l’eccezione • restituisce il controllo al metodo chiamante e lo interrompe, ecc. • restituisce il controllo al main e lo interrompe • restituisce il controllo al Sistema Operativo • visualizza un tracciato delle varie interruzioni e indicato il tipo di eccezione e l’istruzione che l’ha provocata. • Esempio. public static void main(String arg[]) throws FileNotFoundException{ FileReader lettore = new FileReader(nomefile); ……//nomefile è di tipo stringa } • Anche un’eccezione controllata può essere catturata, ma solitamente la si lascia andare. 13 Eccezioni Eccezioni try { //istruzioni in cui si può //verificare l’eccezione } cacth(Classeccezione nomeoggetto){ //cosa fare nel caso si verifichi //l’eccezione } • Se nel metodo ci sono più istruzioni che possono generare eccezioni, si possono inserire più clausole catch ciascuna con la sua eccezione. • Se l’istruzione che solleva l’eccezione viene “catturata” l’esecuzione dell’istruzione si interrompe e viene eseguita la clausola catch, con le istruzioni definite. • Se invece l’eccezione non viene sollevata, la clausola catch non viene eseguita. Eccezioni Eccezioni • Sintassi per catturare un’eccezione. • Esempio. String line = in.next(); int a = Integer.parseInt(line); • Se il valore inserito non è un numero intero, il metodo parseInt “lancia” l’eccezione NumberFormatException; catturiamo l’eccezione: try{ a = Integer.parseInt(line); } catch(NumberFormatException e){ System.out.println(“il valore non e’ intero”); } • Anche il metodo nextInt se non trova un numero intero solleva un’eccezione: InputMismatchException che può essere catturata: try{ a = nextInt(); } catch(InputMismatchException e){ System.out.println(“il valore non e’ intero”); } • In tale modo si salta l’errore e si prosegue, eventualmente riprovando nuovamente la lettura. 14