Primitiver Typ | Größe im Speicher | Wertebereich |
---|---|---|
Byte | 8 Bit | -128 bis 127 |
kurz | 16 Bit | -32768 bis 32767 |
verkohlen | 16 Bit | 0 bis 65536 |
int | 32 Bit | -2147483648 bis 2147483647 |
lang | 64-Bit | -9223372036854775808 bis 9223372036854775807 |
schweben | 32 Bit | (2 hoch -149) bis ((2 hoch -23) * 2 hoch 127) |
doppelt | 64-Bit | (-2 hoch 63) bis ((2 hoch 63) - 1) |
Boolescher Wert | 8 (bei Verwendung in Arrays), 32 (wenn nicht in Arrays verwendet) | richtig oder falsch |
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);
}
}
Die Übergabe einer Zeichenfolge an den Konstruktor ist nur eine mögliche Option.
Hier verwenden wir Zeichenfolgen, da unsere Zahlen die Maximalwerte für long und double überschreiten und wir dem Compiler irgendwie erklären müssen, welche Zahl wir erstellen möchten :)
Übergeben Sie einfach die Zahl
1111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111
an den Konstruktor funktioniert nicht: Java wird versuchen, die übergebene Zahl in einen der primitiven Datentypen zu packen, aber sie passt in keinen von ihnen.
Aus diesem Grund ist die Verwendung einer Zeichenfolge zur Übergabe der gewünschten Zahl eine gute Option. Beide Klassen können automatisch numerische Werte aus den übergebenen Strings extrahieren.
Ein weiterer wichtiger Punkt, den Sie bei der Arbeit mit Klassen mit großen Zahlen beachten sollten, ist, dass ihre Objekte unveränderlich ( Immutable ) sind.
Dank Ihrer Erfahrung mit der String- Klasse und den Wrapper-Klassen für primitive Typen (Integer, Long usw.) sind Sie bereits mit Unveränderlichkeit vertraut.
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);
}
}
Konsolenausgabe:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Wie zu erwarten ist, hat sich unsere Nummer nicht geändert. Um die Additionsoperation auszuführen, müssen Sie ein neues Objekt erstellen, um das Ergebnis der Operation zu erhalten.
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);
}
}
Konsolenausgabe:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Sehen Sie, jetzt funktioniert alles so, wie es sollte :)
Ist Ihnen übrigens aufgefallen, wie ungewöhnlich die Additionsoperation aussieht?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Dies ist ein weiterer wichtiger Punkt. Klassen mit großen Zahlen verwenden nicht die Operatoren + - * /. Stattdessen stellen sie eine Reihe von Methoden bereit. Machen wir uns mit den wichtigsten vertraut (eine vollständige Liste der Methoden finden Sie wie immer in der Oracle-Dokumentation: hier und hier ).
-
Methoden für arithmetische Operationen: add() , subtract() , multiply() , Divide() . Mit diesen Methoden werden jeweils Addition, Subtraktion, Multiplikation und Division durchgeführt.
-
doubleValue() , intValue() , floatValue() , longValue() usw. werden verwendet, um eine große Zahl in einen der primitiven Java-Typen umzuwandeln. Seien Sie vorsichtig, wenn Sie diese Methoden anwenden. Vergessen Sie nicht die Unterschiede in der Bitgröße!
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); } }
Konsolenausgabe:
8198552921648689607
-
Mit min() und max() können Sie den Minimal- und Maximalwert zweier großer Zahlen ermitteln.
Beachten Sie, dass diese Methoden nicht statisch sind!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)); } }
Konsolenausgabe:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
BigDecimal-Rundungsverhalten
Zu diesem Thema gibt es einen eigenen Abschnitt, da das Runden großer Zahlen und das Konfigurieren des Rundungsverhaltens nicht so einfach sind. Sie können die Methode setScale() verwenden , um die Anzahl der Dezimalstellen für eine BigDecimal festzulegen. Angenommen, wir möchten, dass die Zahl 111,5555555555 drei Nachkommastellen hat. Allerdings können wir nicht das erreichen, was wir wollen, indem wir die Zahl 3 als Argument an die setScale() Methode übergeben. Wie oben erwähnt, BigDecimaldient der Darstellung von Zahlen mit strengen Anforderungen an die Rechengenauigkeit. In der aktuellen Form hat unsere Zahl 10 Nachkommastellen. Wir wollen 7 davon weglassen und nur 3 behalten. Dementsprechend müssen wir zusätzlich zur Zahl 3 den Rundungsmodus bestehen. BigDecimal verfügt über insgesamt 8 Rundungsmodi. Das ist eine Menge! Aber wenn Sie die Präzision Ihrer Berechnungen wirklich verfeinern müssen, haben Sie alles, was Sie brauchen. Hier sind also die 8 Rundungsmodi, die BigDecimal bietet :-
ROUND_CEILING – rundet auf
111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN – rundet gegen Null
111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR – rundet ab
111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP – rundet auf, wenn die Zahl nach dem Dezimalpunkt >= 0,5 ist
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN – rundet auf, wenn die Zahl nach dem Dezimalpunkt > 0,5 ist
0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN – Die Rundung hängt von der Zahl links vom Dezimalpunkt ab. Wenn die Zahl links gerade ist, wird abgerundet. Wenn die Zahl links vom Dezimalpunkt ungerade ist, wird aufgerundet.
2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
Die Zahl links von der Dezimalstelle ist 2 (gerade). Die Zahl wird abgerundet. Wir wollen 0 Dezimalstellen, also ist das Ergebnis 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
Die Zahl links vom Dezimalpunkt ist 3 (ungerade). Die Zahl wird aufgerundet. Wir wollen 0 Dezimalstellen, also ist das Ergebnis 4.
-
ROUND_UNNECCESSARY – Dieser Modus wird verwendet, wenn Sie einer Methode einen Rundungsmodus übergeben müssen, die Zahl jedoch nicht gerundet werden muss. Wenn Sie versuchen, eine Zahl mit gesetztem ROUND_UNNECCESSARY-Modus zu runden, wird eine ArithmeticException ausgelöst.
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP – rundet von Null ab.
111.5551 -> setScale(3, ROUND_UP) -> 111.556
Große Zahlen vergleichen
Das ist auch wichtig. Sie werden sich erinnern, dass wir die Methode equal() zum Vergleichen von Objekten in Java verwenden. Die Implementierung wird entweder von der Sprache selbst bereitgestellt (für Standard-Java-Klassen) oder vom Programmierer überschrieben. Bei BigDecimal Objekten wird die Verwendung der Methode equal() für Vergleiche jedoch nicht empfohlen. Dies liegt daran, dass die Methode BigDecimal.equals() nur dann „true“ zurückgibt, wenn die beiden Zahlen den gleichen Wert und die gleiche Skalierung haben: Vergleichen wir das Verhalten der Methode equal() für die Klassen Double und 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));
}
}
Konsolenausgabe:
true
false
Wie Sie sehen können, erwiesen sich für BigDecimal die Zahlen 1,5 und 1,50 als ungleich! Dies lag genau an den Besonderheiten der Implementierung der Methode equal() in der Klasse BigDecimal.
Für einen genaueren Vergleich zweier BigDecimal Objekte ist es besser, die Methode CompareTo() zu verwenden :
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));
}
}
Konsolenausgabe:
0
Die Methode compareTo() hat 0 zurückgegeben, was bedeutet, dass 1,5 und 1,50 gleich sind. Und das ist das Ergebnis, das wir erwartet haben! :) Damit ist unsere heutige Lektion abgeschlossen. Jetzt geht es wieder an die Aufgaben! :) :)
GO TO FULL VERSION