Tipi di dati primitivi

Java definisce otto tipi di dati primitivi:

tipi interi: byte, short, int, long

tipi floating point (o a virgola mobile): float e double

tipo testuale: char

tipo logico-booleano: boolean

 

- Tipi di dati interi, casting e promotion

I tipi di dati interi sono ben quattro: byte, short, int, long. Essi condividono la stessa funzionalità (tutti possono immagazzinare numeri interi positivi o negativi), ma differiscono per quanto riguarda il proprio intervallo di rappresentazione. Infatti, un byte può immagazzinare un intero utilizzando un byte (otto bit), uno short due byte, un int quattro byte ed un long otto byte. Lo schema seguente riassume dettagliatamente i vari intervalli di rappresentazione:

    byte 8 bit -128,..,+127

    short 16 bit -32.768,..,+32.767

    int 32 bit -2.147.483.648,..,+2.147.483.647

    long 64 bit -9.223.372.036.854.775.808,..,9.223.372.036.854.775.807

Per immagazzinare un intero, si possono utilizzare tre forme: decimale, ottale ed esadecimale. Per la notazione ottale basta anteporre al numero intero uno 0 (zero), mentre per la notazione esadecimale, zero e x (indifferentemente maiuscola o minuscola). Ecco qualche esempio d’utilizzo di tipi interi:

byte b=10; //notazione decimale
short s=022; //notazione ottale
int i=1000000000; //notazione decimale
long l=0x12acd; //notazione esadecimale

C’è da fare però una precisazione. Facciamo un esempio:

byte b=50;

Questo statement è corretto. Il numero intero 50 è tranquillamente compreso nell’intervallo di rappresentazione di un byte che va da –128 a +127. Il compilatore determina la grandezza del valore numerico, e controlla se è compatibile con il tipo di dato dichiarato. Allora, consideriamo quest’altro statement:

b=b*2;

Ciò darà luogo ad un errore in compilazione! Infatti, il compilatore non eseguirà l’operazione di moltiplicazione per controllare la compatibilità con il tipo di dato dichiarato, bensì, promuoverà automaticamente la cifra che si trova alla destra dell’espressione di assegnazione ad int, dato che di default assumerà che 2 sia un int. Quindi, se 50*2 è un int, non può essere immagazzinato in b che è un byte. Il fenomeno appena descritto è conosciuto sotto il nome di "promozione automatica nelle espressioni". Ma, evidentemente, 50*2 è immagazzinabile tranquillamente in un byte. Esiste una tecnica per forzare una certa quantità, ad essere immagazzinata in un certo tipo di dato. Questa tecnica è nota con il nome di "cast" (o "casting"). La sintassi da utilizzare per risolvere il nostro problema è:

b=(byte)b*2;

In questo modo, il compilatore sarà avvertito che un’eventuale perdita di precisione è calcolata e sotto controllo.

Bisogna essere però molto prudenti nell’utilizzare il casting in modo corretto. Infatti se scrivessimo:

b=(byte)128;

il compilatore non segnalerà nessun tipo di errore. In realtà, siccome il cast agisce troncando i bit in eccedenza (nel nostro caso, siccome un int utilizza 32 bit, mentre un byte solo 8, saranno troncati i primi 24 bit dell’int), la variabile b avrà il valore di –128 e non di 128!

Notare che, se utilizziamo una variabile long, a meno di cast espliciti, sarà sempre inizializzata con un intero. Quindi se scriviamo:

long l=2000;

Dobbiamo tener ben presente che 2000 è un int per default, ma il compilatore non ci segnalerà errori perché un int in un long può essere tranquillamente immagazzinato. Per la precisione dovremmo scrivere:

long l=(long)2000;

oppure con una sintassi equivalente:

long l=2000L;

Quindi, un cast a long, è possibile anche posponendo una "elle" maiuscola o minuscola dopo il valore intero assegnato. Si preferisce utilizzare la notazione maiuscola, dato che una "elle" minuscola si può confondere con un numero "uno" in alcuni ambienti di sviluppo. Notare che saremo obbligati ad un cast a long, nel caso in cui volessimo assegnare alla variabile l un valore fuori dell’intervallo di rappresentazione di un int.

 

- Tipi di dati a virgola mobile, casting e promotion

Java per i valori floating point utilizza lo standard di decodifica IEEE-754. I due tipi che possiamo utilizzare sono:

    float 32 bit

    double 64 bit

E’ possibile utilizzare la notazione esponenziale o ingegneristica (la "e" può essere sia maiuscola sia minuscola). Per quanto riguarda cast e promotion, la situazione cambia rispetto al caso dei tipi interi. Il default è double e non float. Ciò implica che se vogliamo assegnare un valore a virgola mobile ad un float non possiamo fare a meno di un cast. Per esempio la seguente riga di codice, porterebbe ad un errore in compilazione:

float f=3.14;

Anche in questo caso, il linguaggio ci viene incontro permettendoci il cast con la sintassi breve:

float f=3.14F;

La "effe" può essere sia maiuscola sia minuscola.

Esiste, per quanto ridondante, anche la forma contratta per i double, infatti:

double d=10.12E24;

è equivalente a scrivere:

double d=10.12E24D;

N.B. : ciò che sembra evidente è che il nostro non sia il linguaggio ideale per fare dei calcoli! Un altro classico problema che potrebbe presentarsi, è quando si dividono due numeri interi. Il risultato infatti sarà sicuramente un numero intero! Consiglio saggio: in caso di espressioni aritmetiche, utilizzare solamente double. In altri tempi questo consiglio sarebbe stato considerato folle…

- Tipo di dato logico - booleano

Il tipo di dato boolean, utilizza solo un bit per memorizzare un valore, e gli unici valori che può immagazzinare sono true e false. Per esempio:

boolean b=true;

- Tipo di dato primitivo letterale

Il tipo char ci permette di immagazzinare caratteri (uno per volta). Utilizza l’insieme Unicode per la decodifica. Unicode è uno standard a 16 bit, che contiene tutti i caratteri della maggior parte degli alfabeti del mondo. Fortunatamente l’insieme ASCII, che probabilmente è più familiare al lettore, è un sottoinsieme dello Unicode. I primi 256 caratteri dei due insiemi coincidono. Per maggiori informazioni, visitare il sito www.unicode.org .

Possiamo assegnare ad un char un qualsiasi carattere che si trova sulla nostra tastiera, oppure passargli direttamente una cifra Unicode in esadecimale che identifica univocamente un determinato carattere, anteponendo ad essa il prefisso "u". In qualsiasi caso, dobbiamo comprendere tra apici singoli, il valore da assegnare. Ecco qualche esempio:

 

char primoCarattere=’a’;

    char car=’@’;

    char carattereUnicodeNonIdentificato=’uABC8’;

 

Esiste anche la possibilità di immagazzinare caratteri di escape come:

    ‘ ’ che equivale ad andare a capo

    ‘’ che equivale ad un solo

    ‘ ’ che equivale ad una tabulazione

    ‘’’ che equivale ad un apice singolo

    ‘"’ che equivale ad un doppio apice (virgolette)

    . . .

N.B.: notare che è possibile inserire un carattere in una certa espressione aritmetica, per esempio, sommare un char con un int. Infatti ad ogni carattere corrisponde un numero intero.

 

 



Ti potrebbe interessare anche

commenta la notizia

C'è 1 commento
Sara
Hai dubbi su questo articolo?