Tipo primitivo | Dimensioni in memoria | Intervallo di valori |
---|---|---|
byte | 8 bit | -128 a 127 |
corto | 16 bit | -32768 a 32767 |
char | 16 bit | da 0 a 65536 |
int | 32 bit | Da -2147483648 a 2147483647 |
lungo | 64 bit | -9223372036854775808 a 9223372036854775807 |
galleggiante | 32 bit | (2 elevato a -149) a ((2 elevato a -23) * 2 elevato a 127) |
Doppio | 64 bit | (-2 elevato a 63) a ((2 elevato a 63) - 1) |
booleano | 8 (se utilizzato negli array), 32 (quando non utilizzato negli array) | vero o falso |
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigDecimal decimal = new BigDecimal("123.444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444");
System.out.println(decimal);
}
}
Passare una stringa al costruttore è solo una delle possibili opzioni. Qui usiamo le stringhe, perché i nostri numeri superano i valori massimi per long e double , e abbiamo bisogno di un modo per spiegare al compilatore quale numero vogliamo creare :) Semplicemente passando il numero 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111 al costruttore non funzionerà: Java proverà a stipare il numero passato in uno dei tipi di dati primitivi, ma non si adatterà a nessuno di essi. Ecco perché usare una stringa per passare il numero desiderato è una buona opzione. Entrambe le classi possono estrarre automaticamente valori numerici dalle stringhe passate. Un altro punto importante da ricordare quando si lavora con classi con numeri grandi è che i loro oggetti sono immutabili ( Immutable ). Hai già familiarità con l'immutabilità grazie alla tua esperienza con la classe String e le classi wrapper per i tipi primitivi (Integer, Long, ecc.).
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
integer.add(BigInteger.valueOf(33333333));
System.out.println(integer);
}
}
Uscita console:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Come ci si aspetterebbe, il nostro numero non è cambiato. Per eseguire l'operazione di addizione, è necessario creare un nuovo oggetto per ricevere il risultato dell'operazione.
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigInteger result = integer.add(BigInteger.valueOf(33333333));
System.out.println(result);
}
}
Uscita console:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Vedi, ora tutto funziona come dovrebbe :) A proposito, hai notato quanto sia insolita l'operazione di addizione?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Questo è un altro punto importante. Le classi con numeri grandi non usano gli operatori + - * /. Invece, forniscono una serie di metodi. Facciamo conoscenza con i principali (come sempre, puoi trovare un elenco completo dei metodi nella documentazione di Oracle: qui e qui ).
-
metodi per operazioni aritmetiche: add() , subtract() , multiply() , divide() . Questi metodi vengono utilizzati per eseguire rispettivamente addizioni, sottrazioni, moltiplicazioni e divisioni.
-
doubleValue() , intValue() , floatValue() , longValue() , ecc. sono usati per convertire un numero grande in uno dei tipi primitivi di Java. Fai attenzione quando usi questi metodi. Non dimenticare le differenze nella dimensione dei bit!
import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); long result = integer.longValue(); System.out.println(result); } }
Uscita console:
8198552921648689607
-
min() e max() consentono di trovare il valore minimo e massimo di due grandi numeri.
Si noti che questi metodi non sono statici!import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); BigInteger integer2 = new BigInteger("222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"); System.out.println(integer.max(integer2)); } }
Uscita console:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
Comportamento di arrotondamento BigDecimal
Questo argomento ha una sua sezione separata, poiché l'arrotondamento di numeri grandi e la configurazione del comportamento di arrotondamento non sono così semplici. È possibile utilizzare il metodo setScale() per impostare il numero di posizioni decimali per un BigDecimal . Ad esempio, supponiamo di volere che il numero 111.5555555555 abbia tre cifre dopo la virgola. Tuttavia, non possiamo ottenere ciò che vogliamo passando il numero 3 come argomento al metodo setScale() . Come accennato in precedenza, BigDecimalserve per rappresentare numeri con severi requisiti di precisione computazionale. Nella sua forma attuale, il nostro numero ha 10 cifre dopo la virgola. Vogliamo eliminarne 7 e mantenerne solo 3. Di conseguenza, oltre al numero 3, dobbiamo passare la modalità di arrotondamento. BigDecimal ha un totale di 8 modalità di arrotondamento. Questo è molto! Ma se hai davvero bisogno di mettere a punto la precisione dei tuoi calcoli, avrai tutto ciò di cui hai bisogno. Quindi, ecco le 8 modalità di arrotondamento offerte da BigDecimal :-
ROUND_CEILING — arrotonda per eccesso
111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN — arrotonda verso lo zero
111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR — arrotonda per difetto
111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP — arrotonda per eccesso se il numero dopo la virgola >= 0,5
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN — arrotonda per eccesso se il numero dopo la virgola > 0,5
0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN — l'arrotondamento dipende dal numero a sinistra della virgola decimale. Se il numero a sinistra è pari, l'arrotondamento sarà per difetto. Se il numero a sinistra della virgola è dispari, l'arrotondamento sarà per eccesso.
2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
Il numero a sinistra della cifra decimale è 2 (pari). Il numero è arrotondato per difetto. Vogliamo 0 cifre decimali, quindi il risultato è 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
Il numero a sinistra della virgola è 3 (dispari). Il numero è arrotondato. Vogliamo 0 cifre decimali, quindi il risultato è 4.
-
ROUND_UNNECCESSARY — Questa modalità viene utilizzata quando è necessario passare una modalità di arrotondamento a un metodo, ma non è necessario arrotondare il numero. Se si tenta di arrotondare un numero con la modalità ROUND_UNNECCESSARY impostata, viene generata un'eccezione ArithmeticException.
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP — arrotonda partendo da zero.
111.5551 -> setScale(3, ROUND_UP) -> 111.556
Confronto di grandi numeri
Anche questo è importante. Ricorderai che usiamo il metodo equals() per confrontare gli oggetti in Java. L'implementazione è fornita dal linguaggio stesso (per le classi Java standard) o sovrascritta dal programmatore. Ma nel caso di oggetti BigDecimal , non è consigliabile utilizzare il metodo equals() per i confronti. Questo perché il metodo BigDecimal.equals() restituisce true solo se i 2 numeri hanno lo stesso valore e scala: Confrontiamo il comportamento del metodo equals() per le classi Double e BigDecimal :import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
Double a = 1.5;
Double b = 1.50;
System.out.println(a.equals(b));
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.equals(y));
}
}
Uscita console:
true
false
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.compareTo(y));
}
}
Uscita console:
0
Il metodo compareTo() ha restituito 0, il che significa che 1,5 e 1,50 sono uguali. E questo è il risultato che ci aspettavamo! :) Questo conclude la nostra lezione di oggi. Ora è il momento di tornare ai compiti! :)
GO TO FULL VERSION