Tipul primitiv | Dimensiunea în memorie | Interval de valori |
---|---|---|
octet | 8 biți | -128 până la 127 |
mic de statura | 16 biți | -32768 până la 32767 |
char | 16 biți | 0 la 65536 |
int | 32 de biți | -2147483648 până la 2147483647 |
lung | pe 64 de biți | -9223372036854775808 până la 9223372036854775807 |
pluti | 32 de biți | (2 la puterea lui -149) la ((2 la puterea lui -23) * 2 la puterea lui 127) |
dubla | pe 64 de biți | (-2 la puterea lui 63) la ((2 la puterea lui 63) - 1) |
boolean | 8 (când este folosit în matrice), 32 (când nu este utilizat în matrice) | adevărat sau fals |
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);
}
}
Trecerea unui șir către constructor este doar o opțiune posibilă. Aici folosim șiruri de caractere, deoarece numerele noastre depășesc valorile maxime pentru long și double și avem nevoie de o modalitate de a explica compilatorului ce număr dorim să creăm :) Trecând pur și simplu numărul 11111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111 la constructor nu va funcționa: Java va încerca să înghesuie numărul transmis într-unul dintre tipurile de date primitive, dar nu se va potrivi în niciunul dintre ele. De aceea, folosirea unui șir pentru a trece numărul dorit este o opțiune bună. Ambele clase pot extrage automat valori numerice din șirurile transmise. Un alt punct important de reținut atunci când lucrați cu clase cu număr mare este că obiectele lor sunt imuabile ( Immutable ). Sunteți deja familiarizat cu imuabilitatea datorită experienței dvs. cu clasa String și clasele wrapper pentru tipurile primitive (Integer, Long etc.).
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);
}
}
Ieșire din consolă:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
După cum v-ați aștepta, numărul nostru nu s-a schimbat. Pentru a efectua operația de adăugare, trebuie să creați un nou obiect pentru a primi rezultatul operației.
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);
}
}
Ieșire din consolă:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Vezi, acum totul funcționează așa cum ar trebui :) Apropo, ai observat cât de neobișnuit arată operația de adăugare?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Acesta este un alt punct important. Clasele cu numere mari nu folosesc operatorii + - * /. În schimb, ele oferă un set de metode. Să ne familiarizăm cu principalele (ca întotdeauna, o listă completă a metodelor o găsiți în documentația Oracle: aici și aici ).
-
metode pentru operații aritmetice: adunare() , scădere() , înmulțire() , împărțire() . Aceste metode sunt folosite pentru a efectua adunarea, scăderea, înmulțirea și, respectiv, împărțirea.
-
doubleValue() , intValue() , floatValue() , longValue() etc. sunt folosite pentru a converti un număr mare într-unul dintre tipurile primitive ale Java. Aveți grijă când utilizați aceste metode. Nu uitați de diferențele de dimensiune a biților!
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); } }
Ieșire din consolă:
8198552921648689607
-
min() și max() vă permit să găsiți valoarea minimă și maximă a două numere mari.
Rețineți că aceste metode nu sunt statice!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)); } }
Ieșire din consolă:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
Comportamentul de rotunjire BigDecimal
Acest subiect are propria sa secțiune separată, deoarece rotunjirea numerelor mari și configurarea comportamentului de rotunjire nu sunt atât de simple. Puteți utiliza metoda setScale() pentru a seta numărul de zecimale pentru un BigDecimal . De exemplu, să presupunem că dorim ca numărul 111,5555555555 să aibă trei cifre după virgulă. Cu toate acestea, nu putem realiza ceea ce ne dorim trecând numărul 3 ca argument la metoda setScale() . După cum am menționat mai sus, BigDecimaleste pentru reprezentarea numerelor cu cerințe stricte privind precizia de calcul. În forma sa actuală, numărul nostru are 10 cifre după virgulă zecimală. Vrem să scăpăm 7 dintre ele și să păstrăm doar 3. În consecință, pe lângă numărul 3, trebuie să trecem modul de rotunjire. BigDecimal are un total de 8 moduri de rotunjire. Sunt multe! Dar dacă într-adevăr trebuie să ajustați precizia calculelor dvs., veți avea tot ce aveți nevoie. Deci, iată cele 8 moduri de rotunjire oferite de BigDecimal :-
ROUND_CEILING — rotunjește în sus
111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN — se rotunjește spre zero
111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR — se rotunjește în jos
111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP — rotunjește în sus dacă numărul după virgulă zecimală >= 0,5
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN — rotunjește în sus dacă numărul după virgulă zecimală > 0,5
0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN — rotunjirea depinde de numărul din stânga punctului zecimal. Dacă numărul din stânga este par, rotunjirea va fi în jos. Dacă numărul din stânga punctului zecimal este impar, atunci rotunjirea va fi în sus.
2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
Numărul din stânga zecimalei este 2 (par). Numărul este rotunjit în jos. Vrem 0 zecimale, deci rezultatul este 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
Numărul din stânga punctului zecimal este 3 (impar). Numărul este rotunjit în sus. Vrem 0 zecimale, deci rezultatul este 4.
-
ROUND_UNNECESSARY — Acest mod este utilizat atunci când trebuie să treceți un mod de rotunjire unei metode, dar numărul nu trebuie să fie rotunjit. Dacă încercați să rotunjiți un număr cu modul ROUND_UNNECESSARY setat, este lansată o excepție ArithmeticException.
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP — se rotunjește de la zero.
111.5551 -> setScale(3, ROUND_UP) -> 111.556
Compararea numerelor mari
Acest lucru este, de asemenea, important. Vă veți aminti că folosim metoda equals() pentru a compara obiectele în Java. Implementarea este fie furnizată de limbajul în sine (pentru clasele standard Java) fie suprascrisă de programator. Dar în cazul obiectelor BigDecimal , utilizarea metodei equals() pentru comparații nu este recomandată. Acest lucru se datorează faptului că metoda BigDecimal.equals() returnează adevărat numai dacă cele 2 numere au aceeași valoare și scară: Să comparăm comportamentul metodei equals() pentru clasele Double și 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));
}
}
Ieșire din consolă:
true
false
După cum puteți vedea, pentru BigDecimal , numerele 1,5 și 1,50 s-au dovedit a fi inegale! Acest lucru a fost tocmai din cauza specificului implementării metodei equals() în clasa BigDecimal . Pentru o comparație mai precisă a două obiecte BigDecimal , este mai bine să utilizați metoda compareTo() :
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));
}
}
Ieșire din consolă:
0
Metoda compareTo() a returnat 0, ceea ce înseamnă că 1,5 și 1,50 sunt egale. Și acesta este rezultatul la care ne așteptam! :) Asta se încheie lecția noastră de astăzi. Acum este timpul să ne întoarcem la sarcini! :)
GO TO FULL VERSION