numeri

operazioni aritmetiche con numeri forniti dall'utente

Supponiamo ora di voler calcolare il prodotto di due numeri interi forniti dall'utente. Ragionevolmente dovremo procedere in questo modo: leggere i due numeri, fare il prodotto e quindi visualizzerai i risultati. Bene. L'unico problema è che quando leggiamo il contenuto di un campo testo, questo è di tipo testo (il nome del tipo per Java è String) e Java non consente di sommare o moltiplicare due testi, consente di farlo soltanto utilizzando delle informazioni di tipo numerico.

Il tipo (o tipo di dato) indica le caratteristiche dei valori che una variabile o una espressione può assumere. Il tipo di una variabile viene definito al momento della sua dichiarazione e non può essere cambiato.

Per ottenere la rappresentazione numerica (parliamo adesso di numeri interi) di un testo si fa così: numero = Integer.parseInt( testo ).

Nella funzione che gestirà l'evento, posto che i campi testo degli operandi si chiamino rispettivamente operando1 ed operando2 mentre il campo testo per mostrare il risultato si chiami risultato, immetteremo il seguente frammento di codice:

public void calcola() {
   String testo1, testo2, risposta;
   int numero1, numero2, prodotto;
   testo1 = operando1.getText();
   testo2 = operando2.getText();
   numero1 = Integer.parseInt(testo1);
   numero2 = Integer.parseInt(testo2);
   prodotto = numero1 * numero2;
   risposta = "" + prodotto;
   risultato.setText(risposta);
}

Da osservare come si fa l'operazione inversa, cioè la conversione in testo del risultato a partire dall'intero prodotto. Stiamo parlando dell'ultima riga evidenziata, il procedimento ha questa logica: l'operatore + ha due significati diversi a seconda che si riferisca a numeri o a stringhe; nel primo caso infatti esegue la normale addizione mentre nel secondo caso – come visto in un precedente capitolo – esegue una concatenazione di testi. Osservando la riga in questione (la penultima) vedrai che un argomento dell'operatore è di tipo stringa e l'altro è di tipo intero. Quando uno degli operandi è di tipo stringa, Java rappresenterà anche l'altro operando come stringa, eseguendo così una conversione implicita da intero a testo. Dato che la stringa vuota concatenata ad una seconda stringa (che è il risultato della trasformazione in stringa di prodotto) rende esattamente la seconda stringa, abbiamo ottenuto ciò che si voleva.

Se lunghezza è una variabile di tipo intero e testo è una variabile di tipo String che contine la rappresentazione di un numero come posso fare per avere il valore che rappresenta in lunghezza?

Integer.parseInt(testo,lunghezza)Integer.parseInt() ha un solo argomento qui ne vengono usati due testo=Integer.parseInt(lunghezza)L'argomento dei Integer.parseInt() deve essere il testo, come risultato dà un numero, qui l'argomento è un numero lunghezza=Integer.parseInt(testo)

Per terminare prova ad analizzare la seguente funzione analoga alla precedente:

public void calcola() {
   int numero1, numero2, prodotto;
   numero1 = Integer.parseInt(operando1.getText());
   numero2 = Integer.parseInt(operando2.getText());
   prodotto = n1 * n2;
   risultato.setText("" + prodotto);
}

Come si vede si tratta della sola eliminazione delle variabili stringa che erano state utilizzate per leggere i valori (in questo caso l'istruzione per leggere è stata inserita direttamente in Ineger.parseInt() ) o per calcolare il risultato che andava poi visualizzato.

Crea un programma che calcola l'area e il perimetro di un quadrato, il lato del quadrato è un numero senza parte decimale.

tipi numerici

I tipi fondamentali di Java sono 8 in tutto: di questi ben 6 servono a memorizzare dei numeri, con o senza parte decimale.

I tipi senza parte decimale si differenziano in base al numero più grande (in valore assoluto) che possono contenere, quelli con la parte decimale in base alla precisione che hanno (tecnicamente il numero di cifre per la mantissa e per esponente).

Numeri interi

byte
un numero intero (con segno), occupa 8 bit bit in memoria, i suoi valori vanno da -128 a 127, non si possono scrivere valori diquesto tipo: 34 non è un valore di tipo byte
short
numero intero (con segno), occupa 16 bit in memoria, i suoi valori vanno da -32768 a 32767, non si possono scrivere valori di questo tipo: 678 non è un valore di tipo short
int
numero intero (con segno), occupa 32 bit in memoria, i suoi valori vanno da -2147483648 ... 2147483647, per ricordarci facilmente nell'ordine di ± due miliardi, i valori di questo tipo in si scrivono normalmente: ad esempio456.
long
numero intero (con segno), occupa in memoria 64 bit, i suoi valori vanno da -9223372036854775808 a 9223372036854775807, per ricordarci più facilmente nell'ordine di ± 1018.
I numeri di tipo long si scrivono postponendo una "L" al numero intero, "14456L" è un valore long valido.

Numeri in virgola mobile

Nei numeri in virgola mobile per separare la parte intera da quella decimale si usa il "." come nella notazione Anglosassone e non la "," come nella notazione Italiana.

float
numero in virgola mobile, in memoria occupa 32 bit, il numero più piccolo memorizzabile è circa ±1,45x10-45 e il più grande è circa 3,4x1038 I numeri di tipo float si scrivono utilizzando il "." per separare la parte decimale e postponendo una "f" al numero, "14.456f" è un valore float valido.
double
numero in virgola mobile, in memoria occupa 64 bit, il numero più piccolo memorizzabile è circa ±4,5x10-324 e il più grande è circa 1,7x10308.
I numeri di tipo double si scrivono utilizzando il "." per separare la parte decimale, "14.456" è un valore double valido.

Analogamente a quanto visto per i numeri interi è possibile trasformare un testo in un numero float o double utilizzando rispettivamente Float.parseFloat(stringa) e Double.parseDouble(stringa).

Quale dei seguenti tipi può contenere valori con la parte decimale?

byte no, numeri interi molto piccoli float long no, numero interi molto grandi double

Operatori numerici

I valori numerici vengono utilizzati anche per fare calcoli, quindi per scrivere espressioni (le tratteremo nel dettaglio poco più avanti in questo capitolo), insieme agli operatori.

Un operatore è un simbolo (formato da uno o più caratteri) che serve a produrre un risultato combinando il valore di uno o più operandi.
+
è il solito operatore per l'addizione: 4 + 7 è una espressione ammissibile, anche k + 7 se k è una variabile di tipo numerico
-
con due operandi è la sottrazione, usato nel modo usuale
con un solo operando posto dopo l'operatore è l'inversione di segno
*
moltiplicazione, k * m è una espressione valida se k e m sono due variabili numeriche
/
quoziente, il risultato della divisione. Se si usano variabili in virgola mobile è il risultato che ci si aspetta: 15.0 / 4.0 dà come risultato 3.75. Se si usano valori interi il risultato è quello delle divisioni che si facevano alle elementari! (quelle con il resto) quindi: 10 / 3 fa 3.
%
resto della divisione, anche chiamato modulo. 10 / 3 fa 1

Il risultato di una operazione (l'applicazione di un operatore) è del tipo più preciso tra quelli coinvolti. Se per esempio sommo due int ottengo un int, se sommo un int e un double ottengo un double.

operatori di pre/post incremento

++
se posto prima di una variabile incrementa di uno il suo valore e poi la usa per eseguire il calcolo dell'espressione, se posto dopo i nome della variabile prima usa il valore della variabile stessa per calcolare il resto dell'espressione e poi ne incrementa il valore
--
se posto prima di una variabile decrementa di uno il suo valore e poi la usa per eseguire il calcolo dell'espressione, se posto dopo i nome della variabile prima usa il valore della variabile stessa per calcolare il resto dell'espressione e poi ne decrementa il valore
Gli operatori di pre (o post) incremento possono comparire sia all'interno di espressioni che come istruzioni a se.

Quanto vale x dopo il seguente frammento di programma?

x = 18
x++;
18no, c'era un incremento 19

Quanto vale y dopo il seguente frammento di programma?

x = 3
y = x++ * 2;
6esatto, prima calcola l'espressione e poi fa l'incremento 8no, l'incremento viene fatto dopo il calcolo

Quanto valgono x e y dopo il seguente frammento di programma?

x = 3
y = --x * 3;
x=2 e y=6giusto x=3 e y=6no, x viene decrementata x=2 e y=9no, prima viene fatto il decremento della x e poi calcolata l'espressione x=3 e y=9no, va decrementata la x e poi calcolata l'espressione

conversione di tipo

Non è possibile assegnare un valore più preciso ad un tipo meno preciso... sarebbe a dire che non posso mettere un valore in virgola mobile (ad esempio un double) in una variabile di tipo intero perché si rischierebbe di perdere informazioni quindi se lo faccio java mi rileva un errore.

È possibile però forzare questa operazione quando si è sicuri che il valore sia convertibile usando l'operazione di cast che si fa racchiudendo tra parentesi tonde il nome di un tipo prima di un espessione.

Poniamo che la variabile x sia di tipo int: x=(int) 10.8 converte il valore 10.8 ad un intero (non arrotondando ma troncando il valore) ottenendo quindi 10, questa operazione può essere fatta tra i diversi tipi numerici, attenzione però che la converisone tra i tipi interi viene fatta semplicemente scartando dei byte.

Quanto vale (byte) 257 ?

257no, 257 non è rappresentabile in un byte 255no, i byte per Java hanno un segno... 255 è troppo grande 127no, sarebbe rappresentabile ma i cast non fanno arrotondamenti tra numeri interi 1giusto! 257 in binario è 100000001, siccome viene preso il solo byte più a destra il risultato è 1

L'operazione di cast può essere fatta anche in altri contesti, qui ci siamo limitati a trattarla tra tipi base.

Espressioni

Viene detta espressione una combinazione di valori e funzioni da cui si ottiene un nuovo valore. Il tipo dell'espressione è il tipo del risultato ottenuto.

Sembra complicato? forse risulterà più semplice facendo alcuni esempi, teniamo conto soltanto delle seguenti dichiarazioni:

int x = 5;
int y = 7;
double m = 2.00;
String s = "11";

E proviamo a vedere alcune espressioni e il loro tipo:

x + y
Questa espressione combina due informazioni (variabili) di tipo int e quindi è una espressione di tipo int, il suo valore è 12
x * 3
Questa espressione combina due informazioni (una variabile e una costante) di tipo int e quindi è una espressione di tipo int, il suo valore è 15
4
Anche questa è una espressione, ha una sola costante di tipo int e quindi è un espressione di tipo int, il suo valore è 4
Integer.parseInt(s)
Integer.parseInt() è una funzione che da un risultato di tipo int: di nuovo una espressione int, il suo valore è 11
Integer.parseInt(s) + 18
Integer.parseInt() è una funzione che da un risultato di tipo int, sommato ad un altro int... di nuovo una espressione intera, 29 per la precisione.
y * m
siccome le due variabili sono di tipi diversi il risultato è del tipo più "ampio", cioè che consente di rappresentare il numero più grande: double, il suo valore è 14.00
(int)(m*1.3)
m e 1.3 sono double quindi il risultato è double ma c'è un cast: il tipo dell'espressione è int (ma il prodotto viene fatto tra due double quindi è double che poi verrà convertito in int) e il suo valore è 2
y + x++
tutte variabili int, il suo tipo è int, il valore è 12, questa espressione cambia anche il valore di x che diventerà 6

Precedenza degli operatori

Nelle espressioni del linguaggio linguaggio Java gli operatori hanno la precedenza usuale ma per un riferimento più preciso è disponibile una pagina del tutorial di Oracle.

Nella scrittura delle espressioni per modificare l'ordine in cui vanno eseguite le operazioni possono essere utilizzate soltanto le parentesi tonde.

Quanto vale 6 + 4 / 2 ?

8esatto 5no, viene fatta prima la divisione

Quanto vale l'espressione 4+5*2?

18no, prima si fa il prodotto erroreno, l'espressione è corretta 14

Quale è il tipo dell'espressine 4+5*2?

doubleno, non sono numeri con una parte decimale int erroreno, l'espressione è corretta e ha un tipo

Quanto vale [6 + (2 * 2) ] / 2 ?

5no, le parentesi quadre non posso essere usate 4no, le parentesi quadre non posso essere usate erroregiusto, le parentesi quadre non posso essere usate