Primitiv typ | Storlek i minnet | Värdeintervall |
---|---|---|
byte | 8 bitar | -128 till 127 |
kort | 16 bitar | -32768 till 32767 |
röding | 16 bitar | 0 till 65536 |
int | 32 bitar | -2147483648 till 2147483647 |
lång | 64 bitar | -9223372036854775808 till 9223372036854775807 |
flyta | 32 bitar | (2 till -149) till ((2 i -23) * 2 till 127) |
dubbel | 64 bitar | (-2 till 63) till ((2 till 63) - 1) |
booleskt | 8 (när den används i arrayer), 32 (när den inte används i arrayer) | sant eller falskt |
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);
}
}
Att skicka en sträng till konstruktorn är bara ett möjligt alternativ. Här använder vi strängar, eftersom våra siffror överstiger maxvärdena för long och double , och vi behöver något sätt att förklara för kompilatorn vilket nummer vi vill skapa :) Skicka bara numret 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 till konstruktorn kommer inte att fungera: Java kommer att försöka klämma in det passerade numret i en av de primitiva datatyperna, men det kommer inte att passa in i någon av dem. Det är därför det är ett bra alternativ att använda en sträng för att skicka det önskade numret. Båda klasserna kan automatiskt extrahera numeriska värden från de passerade strängarna. En annan viktig punkt att komma ihåg när du arbetar med klasser med stora antal är att deras objekt är oföränderliga ( Immutable ). Du är redan bekant med oföränderlighet tack vare din erfarenhet av String -klassen och omslagsklasserna för primitiva typer (heltal, lång, 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);
}
}
Konsolutgång:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Som du kan förvänta dig har vårt nummer inte ändrats. För att utföra tilläggsoperationen måste du skapa ett nytt objekt för att få resultatet av operationen.
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);
}
}
Konsolutgång:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Se, nu fungerar allt som det ska :) Har du förresten märkt hur ovanlig tilläggsoperationen ser ut?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Detta är en annan viktig punkt. Klasser med stora siffror använder inte operatorerna + - * /. Istället tillhandahåller de en uppsättning metoder. Låt oss bekanta oss med de viktigaste (som alltid kan du hitta en komplett lista över metoder i Oracle-dokumentationen: här och här ).
-
metoder för aritmetiska operationer: add() , subtrahera() , multiplicera() , divide() . Dessa metoder används för att utföra addition, subtraktion, multiplikation respektive division.
-
doubleValue() , intValue() , floatValue() , longValue() , etc. används för att konvertera ett stort tal till en av Javas primitiva typer. Var försiktig när du använder dessa metoder. Glöm inte skillnaderna i bitstorlek!
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); } }
Konsolutgång:
8198552921648689607
-
min() och max() låter dig hitta det lägsta och högsta värdet för två stora tal.
Observera att dessa metoder inte är statiska!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)); } }
Konsolutgång:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
BigDecimal avrundningsbeteende
Det här ämnet har ett eget separat avsnitt, eftersom avrundning av stora tal och konfigurering av avrundningsbeteende inte är så enkelt. Du kan använda metoden setScale() för att ställa in antalet decimaler för en BigDecimal . Anta till exempel att vi vill att talet 111.5555555555 ska ha tre siffror efter decimalkomma. Men vi kan inte uppnå vad vi vill genom att skicka siffran 3 som ett argument till metoden setScale() . Som nämnts ovan, BigDecimalär för att representera tal med strikta krav på beräkningsprecision. I sin nuvarande form har vårt nummer 10 siffror efter decimalkomma. Vi vill släppa 7 av dem och bara behålla 3. Därför måste vi, förutom siffran 3, klara avrundningsläget. BigDecimal har totalt 8 avrundningslägen. Det är mycket! Men om du verkligen behöver finjustera precisionen i dina beräkningar har du allt du behöver. Så här är de 8 avrundningslägena som erbjuds av BigDecimal :-
ROUND_CEILING — avrundar uppåt
111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN — avrundar mot noll
111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR — avrundar nedåt
111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP — avrundar uppåt om talet efter decimalkomma >= 0,5
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN — avrundar uppåt om talet efter decimalkomma > 0,5
0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN — avrundning beror på talet till vänster om decimalkomma. Om siffran till vänster är jämn blir avrundningen nedåt. Om siffran till vänster om decimaltecknet är udda, kommer avrundningen att vara uppåt.
2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
Siffran till vänster om decimalen är 2 (jämnt). Antalet avrundas nedåt. Vi vill ha 0 decimaler, så resultatet är 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
Siffran till vänster om decimalkomma är 3 (udda). Antalet avrundas uppåt. Vi vill ha 0 decimaler, så resultatet är 4.
-
ROUND_UNNECCESSARY — Detta läge används när du måste skicka ett avrundningsläge till en metod, men talet behöver inte avrundas. Om du försöker avrunda ett tal med läget ROUND_UNNECCESSARY inställt, kastas ett ArithmeticException.
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP — avrundar bort från noll.
111.5551 -> setScale(3, ROUND_UP) -> 111.556
Jämför stora siffror
Detta är också viktigt. Du kommer ihåg att vi använder metoden equals() för att jämföra objekt i Java. Implementeringen tillhandahålls antingen av själva språket (för standard Java-klasser) eller åsidosätts av programmeraren. Men i fallet med BigDecimal- objekt rekommenderas inte metoden equals() för jämförelser. Detta beror på att metoden BigDecimal.equals() returnerar true endast om de två talen har samma värde och skala: Låt oss jämföra beteendet för metoden equals() för klasserna Double och 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));
}
}
Konsolutgång:
true
false
Som du kan se, för BigDecimal , visade sig siffrorna 1,5 och 1,50 vara ojämlika! Detta var just på grund av detaljerna i implementeringen av metoden equals() i BigDecimal -klassen. För en mer exakt jämförelse av två BigDecimal- objekt är det bättre att använda metoden 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));
}
}
Konsolutgång:
0
Metoden compareTo() returnerade 0, vilket betyder att 1,5 och 1,50 är lika. Och det här är resultatet vi förväntade oss! :) Det avslutar vår lektion idag. Nu är det dags att återgå till uppgifterna! :)