Indice Indice 1 Tipi numerici 1 1.1 Tipi interi................................................. 2 1.2 Virgola mobile.............................................. 2 2 Conversioni e promozioni 4 2.1 Tipi ed espressioni............................................ 5 3 Array di tipi primitivi 6 3.1 Array monodimensionali......................................... 6 3.2 Array multidimensionali......................................... 8 1 Tipi numerici Tipi numerici Tipo Contiene Default Size Range char car Unicode \u 16 bit da \u a \uffff byte int con segno 8 bit da 2 7 a 2 7 1 short int con segno 16 bit da 2 15 a 2 15 1 int int con segno 32 bit da 2 31 a 2 31 1 long int con segno 64 bit da 2 63 a 2 63 1 float Std IEEE 754. 32 bit (± 1.4E-45, ± 3.4E+38) double Std IEEE 754. 64 bit (± 4.9E-324, ± 1.8E+38) Osservazione: 1 2 3.32, da cui si ha che 2 31 1 31 3.32 2 1 9 Letterali numerici char c = xffff; // massimo valore char (hex) byte b = x7f; // massimo valore byte (hex) short s = x7fff; // massimo valore short (hex) int i1 = x2f; // Hexadecimal (minuscolo) int i2 = X2F; // Hexadecimal (maiuscolo) int i3 = 177; // Ottale (zero seg. da cifre 1..7) long n1 = 2L; // suffisso long long n2 = 2l; // suffisso long long n3 = 2; float f1 = 1; float f2 = 1F; // suffisso float float f3 = 1f; // suffisso float float f4 = 1e-45f; // 1ˆ(-45) float f5 = 1e+9f; // suffisso float double d1 = 1d; // suffisso double double d2 = 1D; // suffisso double double d3 = 47e47d; // 1ˆ(47)
1.1 Tipi interi Aritmetica modulare Con l aritmetica intera non si verificano overflow o underflow int i = 1; // int j = 1; // out.println(i * j); 1ˆ6 1ˆ6 i = 2147483647; // 2ˆ31-1 out.println(i + 1); i = -2147483648; // -2ˆ31 out.println(i - 1); Aritmetica modulare Output prompt> -727379968 prompt> -2147483648 prompt> 2147483647 Doppia precisione intera long l = 92233723685477587; // non compila! long l = 92233723685477587L; // 2ˆ63-1 // ordine 1ˆ18 out.println(l + 1); prompt> -92233723685477588 1.2 Tipi in virgola mobile Aritmetica in virgola mobile Overflow e underflow in virgola mobile double d = 1e38; out.print("l overflow produce infinito: "); out.println(d + "*1==" + d*1); out.println("underflow graduale:"); d = 1e-35 * 3.14; out.println(d); for (i = ; i < 4; i++) out.println(d /= 1); Aritmetica in virgola mobile Output prompt> 1.E38*1==Infinity prompt> 3.14E-35 3.14E-31 3.14E-315 3.14E-32. 2
Aritmetica in virgola mobile Non è un numero! // Un esempio di NaN: out.print("./., cioe Not-a-Number: "); d =./.; out.println(d); prompt>./., cioe Not-a-Number: NaN // e nel caso intero? out.print("/ = " + /); Aritmetica in virgola mobile Risultato non corretto per effetto di arrotondamenti out.print("risultato non corretto con i float:"); for (i = ; i < 1; i++) { float z = 1.f / i; if (z * i!= 1.f) out.print(" " + i); out.print("risultato non corretto con i double:"); for (i = ; i < 1; i++) { double z = 1. / i; if (z * i!= 1.) out.print(" " + i); Aritmetica in virgola mobile Output prompt> 41 47 55 61 82 83 94 97 prompt> 49 98 Letterali di default int per i tipi numerici interi byte b = 1; int i = 1; long l = 1L; double per i tipi floating point float s = 1; // compila float s = 1.3; // non compila float s = 1.3f; // compila double d = 1.3; // compila 3
2 Conversioni e promozioni Tipi di conversione: riassunto Esistono due tipi di conversione in Java: widening conversion (= ampliamento, promozione) si verifica quando un valore numerico di un dato tipo viene assegnato a una variabile il cui tipo supporta un insieme di valori più esteso narrowing conversion (= restringimento, forzatura) si verifica quando un valore numerico di un dato tipo viene assegnato a una variabile il cui tipo supporta un insieme di valori meno esteso Nel primo caso le conversioni sono implicite (o automatiche). Nel secondo caso devono essere rese esplicite (o forzate) con il costrutto cast Conversioni di tipi: tabella riassuntiva Da: A: byte short char int long float double byte - W N W W W W short N - N W W W W char N N - W W W W int N N N - W W W long N N N N - W W float N N N N N - W double N N N N N N - N = narrowing (restringimento) W = widening (ampliamento) W = widening con possibile perdita di cifre meno significative Cast Necessità del cast nelle operazioni aritmetiche int i = 1;// i = 1... int j = 3*i; // j = -1.294.967.296 long k = 3*i; // k = -1.294.967.296 long w = (long)3*i;// w = 3... Cast richiesto dal controllo sui tipi byte b = 1; // non compila int i = 1; byte b = i; // non compila byte b = (byte)i; char c = (char)i; double d = 1.33; float f = d; // non compila float f = (double)d; Perdita d informazione Assegnamento accettato senza cast (widening) // perdita d informazione i = 123456789; float f = i; out.println("f - i = " + ((int)f - i)); 4
long p = 123456789123456789L; double q = p; out.println("q - p = " + ((long)q - p)); Perdita d informazione Output prompt>f - i = 46 prompt>q - p = -21 2.1 Tipi ed espressioni Espressioni semplici Il più semplice tipo di espressioni consite di letterali e variabili (espressioni semplici) Esempi: 13.452; // letterale floating point somma; // variabile L interprete Java valuta un espressione e ne restituisce il valore Se si tratta di un letterale è il valore rappresentato dal letterale stesso Se si tratta di una variabile il valore in essa contenuto Espressioni composte Le espressioni composte si ottengono combinando opportunamente espressioni semplici e operatori Esempi: // operatori di prodotto e divisione area = base * altezza / 2; // invocazione di metodo in.readdouble(); Osservazione: l invocazione di metodo costituisce anch essa un espressione semplice Operatori e operandi Gli operandi sono gli argomenti dell operatore. Alcuni operatori operano solo su un operando (operatore unario), altri ne richiedono due (operatore binario) ecc. Java ha operatori unari, binari e ternari (un solo caso!) Ogni operatore si aspetta che i suoi operandi siano di un particolare tipo Fissato l operatore e il tipo degli operandi è univocamente determinato il tipo del risultato dell espressione Ogni espressione ha un tipo determinato da quello dei suoi componenti e dalla semantica degli operatori coinvolti. 5
Conversioni implicite di tipo Precedenze tra operatori Tipo ris. long int double Tipo degli operandi Nessun operando è un float o un double (aritmetica intera); ma almeno uno è un long Nessun operando è un float o un double (aritmetica intera); nessun operando è un long Almeno un operando è un double. float Almeno un operando è un float; nessun operando è un double. Tipo di operatore 3 Array di tipi primitivi 3.1 Calcolo delle permutazioni Problema Operatore Postfissi []. (parametri) expr++ expr-- Unari ++expr --expr +expr -expr! Creazione e conversione new (tipo)expr Moltiplicativi * / % Additivi + - Scorrimento << >> >>> Relazionali < > <= >= instanceof Uguaglianza ==!= AND &...... Condizionale?: Assegnamenti = += -= *= /= %= Permutazioni Scrivere un programma Java che stampi n > permutazioni casuali di un insieme di numeri assegnato Che cosa si intende per permutazione? Progettazione Metodo top down... 1 2 3 4 5 6 7 8 9 1 3 6 1 9 1 7 2 4 8 5 Definizione dei sottoproblemi acquisire dall utente il numero di permutazioni richieste effettuare una copia dell array da elaborare (così da mantenere inalterato l originale) determinare le permutazioni casuali dell insieme richieste stampare le permutazioni 6
Copia di un array - 1 Dato l array definito (creazione + inizializzazione) di seguito: int[] insieme = {1,2,3,4,5,6,7,8,9,1; E corretto effettuare la copia nel seguente modo? int[] copiadiinsieme = insieme; Cosa accade in realtà? insieme int[] copiadiinsieme 1 2 3 4 5 6 Errore semantico! I due riferimenti puntano allo stesso oggetto Copia di un array - 2 int copiadiinsieme[] = new int[insieme.length]; for (int i=; i < insieme.length; i++) copiadiinsieme[i] = insieme[i]; insieme int[] 4 2 5 6 8 9 1 1 2 3 4 5 6 copiadiinsieme int[]... 4 2 1 2 3 4 5 6 Un corollario dell inizializzazione Example 3.1. Istruzione di inizializzazione:[2em] int i = 1; int[] tredispari = {2*i+1,2*(i+1)+1,2*(i+2)+1; [2em] Poiché Java inizializza esplicitamente gli array a runtime, allora anche le espressioni possono essere usate al posto delle costanti. Il compilatore si limita a verificare la congruenza tra il tipo delle singole espressioni con il tipo base dell array Determinare una permutazione Individuazione dei sottoproblemi Prendere in esame la copia dell array originale (modificabile a piacere secondo gli scopi) Generare una sequenza di numeri intero a caso nell intervallo [, N 1]: vedi il metodo randint della classe java.util.random Indicizzare con tale insieme l array, copiare i numeri ivi contenuti nel nuovo array o stamparli, marcardo ogni volta l elemento letto Soluzione Vedi il programma Permutazioni.java... N.B. Il ciclo while potrebbe essere molto inefficiente... modificare il programma sostituendo con un ciclo for. 7
3.2 Algebra delle matrici Array multidimensionali Un array multidimensionale è un array i cui elementi sono a loro volta array Il caso più semplice è quello in cui gli elementi sono array monodimensionali. In questo caso si ottengono delle strutture chiamate matrici (array di dimensione 2). 1 2 3 1 4 7 2 4 12 6 9 riga (seconda) 2 17 5 22 3 Esempio: matrice 3x4 (3 righe e 4 colonne) colonna (terza) Array: dichiarazione e accesso 1 2 3 1 4 7 2 4 12 6 9 riga (seconda) 2 17 5 22 3 colonna (terza) Dichiarazione: int[][] matrice = new int[3][4]; Accesso all elemento memorizzato nella seconda riga & terza colonna: int i = matrice[1][2]; Dimensioni: il numero di righe è dato da matrice.length, il numero di colonne è dato da matrice[].length Array: dichiarazione (2) Nella dichiarazione, una o più dimensioni possono non essere specificate: in questo caso gli elementi corrispondenti alle dimensioni non specificate sono riferimenti vuoti (null) Esempio: int[][] a = new int[3][]; dichiara una array di 3 elementi che sono riferimenti ad array monodimensionali di lunghezza non specificata. Sarà quindi necessario inizializzare ogni elemento usando l operatore new. Cioè: a[] = new int[1]; a[1] = new int[7]; a[2] = new int[22]; Array: situazione in memoria Un array multidimensionale viene memorizzato come un array di array 8
(4) 4 1 2 1 2 3 4 7 2 4 12 6 9 17 5 22 3 matrice length (3) 7 2 4 (4) 17 5 22 (4) 12 6 9 3 Array: inizializzazione Analogamente agli array monodimensionali, anche gli array multidimensionali possono essere inizializzati in fase di dichiarazione class Motto{ public static void main (String args []){ char motto [][] = { { E, s, t, o, t, e, { p, a, r, a, t, e,.,.,. ; out.println (new String(motto[])); out.println (new String(motto[1])); Esercizio: somma di matrici Problema Scrivere un programma Java che, date due matrice di numeri, restituisca la matrice somma Esempio: somma elementi matrice class SommaMatrice{ // Somma gli elementi della matrice A public static void main (String [] args){ int[][] A = { {1, 2, 3, 4, 5, {4, 8, 3, 2, 7, {1, 7, 3, 6, 8, {9, 2, 8, 3, 1; int somma=; for (int i=; i< A.length; i++) for (int j=; j< A[i].length; j++) somma += A[i][j]; out.println (somma); 9
Esercizio: prodotto di matrici Il prodotto di matrici è illustrato come segue: date una matrice 3x4 e una 4x2... x = 3 x 4 4 x 2 3 x 2 Problema Scrivere un programma Java che, date due matrice di numeri, ne effettui il prodotto e lo stampi a video Le matrici Matrice B (6x3) 4 6-3 Matrice A (4x6) 5-1 -5 3 1 2 5-6 12 2 7-1 1-4 1-8 24 2-2 5-4 4 5 19-4 6 11 9-9 -2 33 16 11-5 Matrice prodotto (4x3) -23 141 1 33-13 -82-15 71 33-273 851 664 Soluzione Vedi il programma ProdottoMatrici.java... 1