From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100117.html | 555 +++++++++++++++++++++ 1 file changed, 555 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100117.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100117.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100117.html b/Master/Reference Architectures and Patterns/hjp5/html/k100117.html new file mode 100644 index 0000000..77a04e5 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100117.html @@ -0,0 +1,555 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 17 - Utility-Klassen II +
+
+ + + + +

17.3 Die Klassen BigInteger und BigDecimal

+
+ +
+ +

+Seit dem JDK 1.1 gibt es das Paket java.math +mit den beiden Klassen BigInteger +und BigDecimal. +Beide implementieren beliebig große bzw. beliebig genaue Zahlen +und stellen Methoden zur Durchführung arithmetischer Berechnungen +zur Verfügung. Während BigInteger +beliebig große Ganzzahlen implementiert, dient BigDecimal +zur Darstellung sehr großer Fließkommazahlen. Objekte +beider Klassen sind immutable, d.h. sie können nach der +Instanzierung nicht mehr verändert werden. + + + + +

17.3.1 Die Klasse BigInteger

+ +

+Die einfachste Art, ein BigInteger-Objekt +zu konstruieren, besteht darin, eine String-Repräsentation der +darzustellenden Zahl an den Konstruktor zu übergeben. Das kann +wahlweise mit oder ohne Angabe des Zahlensystems geschehen: +

+ + + + + +
+ +
+public BigInteger(String val)
+
+public BigInteger(String val, int radix)
+
+
+
+java.math.BigInteger
+ +

+Wird das Zahlensystem nicht angegeben, erwartet der Konstruktor eine +Zahl zur Basis 10. Der übergebene String darf eine beliebig lange +Folge von Ziffern sein. An erster Stelle kann ein Minuszeichen stehen, +um eine negative Zahl anzuzeigen. + +

+Die Arithmetik auf BigInteger-Zahlen +erfolgt durch Aufruf ihrer arithmetischen Methoden und Übergabe +der erforderlichen Argumente, die meist ebenfalls vom Typ BigInteger +sind. Der Methodenaufruf verändert dabei nicht den Wert des Objekts, +sondern gibt das Ergebnis als neue BigInteger-Zahl +an den Aufrufer zurück. Wichtige arithmetische Methoden sind: + + +

+ + + + + +
+ +
+public BigInteger add(BigInteger val)
+public BigInteger subtract(BigInteger val)
+public BigInteger multiply(BigInteger val)
+public BigInteger divide(BigInteger val)
+public BigInteger remainder(BigInteger val)
+public BigInteger pow(int exponent)
+
+
+
+java.math.BigInteger
+ +

+Sie berechnen die Summe, Differenz, Produkt, Quotient, Restwert und +Potenz zweier BigInteger-Zahlen. +Neben den Grundrechenarten gibt es weitere Funktionen: + +

+ + + + + +
+ +
+public BigInteger abs()
+public BigInteger negate()
+public int signum()
+public BigInteger gcd(BigInteger val)
+
+public BigInteger min(BigInteger val)
+public BigInteger max(BigInteger val)
+
+
+
+java.math.BigInteger
+ +

+Sie stellen den absoluten Betrag zur Verfügung, multiplizieren +mit -1, liefern das Vorzeichen und ermitteln den größten +gemeinsamen Teiler zweier Zahlen. min +und max +liefern den kleineren bzw. größeren Wert aus aktueller +und als Argument übergebener Zahl. Daneben gibt es logische und +bitweise Operationen, die denen der primitiven ganzzahligen Typen +entsprechen. + +

+Zum Vergleich zweier BigInteger-Zahlen +kann compareTo +und equals +verwendet werden, die Konvertierung in einen String wird mit toString +erledigt: +

+ + + + + +
+ +
+public int compareTo(BigInteger val)
+public boolean equals(Object x)
+
+public String toString()
+
+
+
+java.math.BigInteger
+ +

+Die Arbeitsweise dieser Methoden entspricht der in der Klasse Object +und dem Interface Comparable +definierten und kann in Abschnitt 8.1.2 +und Abschnitt 9.2 nachgelesen +werden. Schließlich gibt es noch einige Methoden, um BigInteger-Objekte +in primitive Typen zu verwandeln: +

+ + + + + +
+ +
+public int intValue()
+public long longValue()
+public float floatValue()
+public double doubleValue()
+
+
+
+java.math.BigInteger
+ +

+Die Umwandlung folgt den in Abschnitt 4.6 +beschriebenen Regeln für einschränkende Konvertierungen. + +

+Als abschließendes Beispiel wollen wir uns ein kleines Programm +ansehen, das die Fakultäten der Zahlen 30 bis 40 berechnet: + + +

+ + + + + +
+ +
+001 /* Listing1705.java */
+002 
+003 import java.math.*;
+004 
+005 public class Listing1705
+006 {
+007   public static void printFaculty(int n)
+008   {
+009     BigInteger bi = new BigInteger("1");
+010     for (int i = 2; i <= n; ++i) {
+011       bi = bi.multiply(new BigInteger("" + i));
+012     }
+013     System.out.println(n + "! is " + bi.toString());
+014   }
+015 
+016   public static void main(String[] args)
+017   {
+018     for (int i = 30; i <= 40; ++i) {
+019       printFaculty(i);
+020     }
+021   }
+022 }
+
+
+Listing1705.java
+ +Listing 17.5: Anwendung der Klasse BigInteger

+ +

+Die Ausgabe des Programms ist: + +

+30! is 265252859812191058636308480000000
+31! is 8222838654177922817725562880000000
+32! is 263130836933693530167218012160000000
+33! is 8683317618811886495518194401280000000
+34! is 295232799039604140847618609643520000000
+35! is 10333147966386144929666651337523200000000
+36! is 371993326789901217467999448150835200000000
+37! is 13763753091226345046315979581580902400000000
+38! is 523022617466601111760007224100074291200000000
+39! is 20397882081197443358640281739902897356800000000
+40! is 815915283247897734345611269596115894272000000000
+
+ + + + + +

17.3.2 Die Klasse BigDecimal

+ +

+Die Klasse BigDecimal +kann beliebig genaue Fließkommazahlen darstellen. Sie bestehen +aus einer Ziffernfolge (die als Objekt vom Typ BigInteger +gespeichert ist) und einer Skalierung, die als nicht-negative +Ganzzahl gespeichert wird. Die Skalierung bestimmt die Anzahl der +Nachkommastellen. Der Wert der Zahl ergibt sich aus der Formel Unskalierter +Wert / (10 Skalierung). + +

+Die Instanzierung eines BigDecimal-Objekts +kann analog zur Klasse BigInteger +durch Übergabe eines Strings an den Konstruktor erfolgen. Dabei +ist neben dem ganzzahligen Teil zusätzlich ein Dezimalpunkt und +ein Gleitkommateil erlaubt. Die Anzahl der Nachkommastellen bestimmt +die Skalierung. Alternativ kann das Objekt auch aus einem BigInteger +oder einem double +konstruiert werden: +

+ + + + + +
+ +
+public BigDecimal(BigInteger val)
+public BigDecimal(double val)
+public BigDecimal(String val)
+
+
+
+java.math.BigDecimal
+ +

+BigDecimal +stellt elementare arithmetischen Funktionen zur Verfügung: +

+ + + + + +
+ +
+public BigDecimal add(BigDecimal val)
+public BigDecimal subtract(BigDecimal val)
+public BigDecimal multiply(BigDecimal val)
+public BigDecimal divide(BigDecimal val, int roundingMode)
+
+public BigDecimal abs()
+public BigDecimal negate()
+public int signum()
+
+public BigDecimal min(BigDecimal val)
+public BigDecimal max(BigDecimal val)
+
+
+
+java.math.BigDecimal
+ +

+Ihr Verhalten entspricht weitgehend dem bei BigInteger +beschriebenen. Eine Ausnahme bildet die Methode divide, +denn sie benötigt zusätzlich eine Konstante, die die Art +der Rundung (falls erforderlich) bestimmt: +

+ +

+Auch die Konvertierungs- und Vergleichsmethoden entsprechen denen +der Klasse BigInteger: +

+ + + + + +
+ +
+public int compareTo(BigDecimal val)
+public boolean equals(Object x)
+
+public String toString()
+
+public int intValue()
+public long longValue()
+public float floatValue()
+public double doubleValue()
+
+
+
+java.math.BigDecimal
+ +

+Mit Hilfe der Methoden scale +und setScale +kann die Skalierung abgefragt bzw. ein neues Objekt mit geänderter +Skalierung erzeugt werden: +

+ + + + + +
+ +
+public int scale()
+
+public BigDecimal setScale(int scale)
+public BigDecimal setScale(int scale, int roundingMode)
+
+
+
+java.math.BigDecimal
+ +

+Das Ändern der Skalierung läßt den numerischen Wert +des Objekts intakt und verändert lediglich die Anzahl der darstellbaren +Dezimalstellen. Soll diese verkleinert werden, muss die zweite Variante +von setScale +verwendet und eine passende Rundungskonstante übergeben werden. +Soll die Anzahl der Dezimalstellen vergrößert werden, kann +die erste Variante verwendet werden. + +

+Zusätzlich gibt es zwei Methoden, mit denen der Dezimalpunkt +um eine bestimmte Anzahl Stellen nach links oder rechts verschoben +werden kann, also eine Multiplikation bzw. Division mit einer Zehnerpotenz +ausgeführt wird: +

+ + + + + +
+ +
+public BigDecimal movePointLeft(int n)
+public BigDecimal movePointRight(int n)
+
+
+
+java.math.BigDecimal
+ +

+Zum Abschluss wollen wir uns ein Beispielprogramm ansehen, das die +Quadratwurzel der Zahl 2 in (theoretisch) beliebiger Genauigkeit errechnen +kann: + + +

+ + + + + +
+ +
+001 /* Listing1706.java */
+002 
+003 import java.math.*;
+004 
+005 public class Listing1706
+006 {
+007   public static final BigDecimal ZERO = new BigDecimal("0");
+008   public static final BigDecimal ONE  = new BigDecimal("1");
+009   public static final BigDecimal TWO  = new BigDecimal("2");
+010 
+011   public static BigDecimal sqrt(BigDecimal x, int digits)
+012   {
+013     BigDecimal zero = ZERO.setScale(digits + 10);
+014     BigDecimal one  = ONE.setScale(digits + 10);
+015     BigDecimal two  = TWO.setScale(digits + 10);
+016     BigDecimal maxerr = one.movePointLeft(digits);
+017     BigDecimal lower = zero;
+018     BigDecimal upper = x.compareTo(one) <= 0 ? one : x;
+019     BigDecimal mid;
+020     while (true) {
+021       mid = lower.add(upper).divide(two, BigDecimal.ROUND_HALF_UP);
+022       BigDecimal sqr = mid.multiply(mid);
+023       BigDecimal error = x.subtract(sqr).abs();
+024       if (error.compareTo(maxerr) <= 0) {
+025         break;
+026       }
+027       if (sqr.compareTo(x) < 0) {
+028         lower = mid;
+029       } else {
+030         upper = mid;
+031       }
+032     }
+033     return mid;
+034   }
+035 
+036   public static void main(String[] args)
+037   {
+038     BigDecimal sqrtTwo = sqrt(TWO, 100);
+039     BigDecimal apxTwo  = sqrtTwo.multiply(sqrtTwo);
+040     System.out.println("sqrt(2): " + sqrtTwo.toString());
+041     System.out.println("check  : " + apxTwo.toString());
+042   }
+043 }
+
+
+Listing1706.java
+ +Listing 17.6: Anwendung der Klasse BigDecimal

+ +

+Das Programm arbeitet mit einer Intervallschachtelung. Dazu werden +zunächst passende Unter- und Obergrenzen gesucht, so dass das +Quadrat der Untergrenze auf jeden Fall kleiner gleich und das Quadrat +der Obergrenze größer oder gleich der gesuchten Zahl ist. +Nun wird der Wert genau in der Mitte zwischen beiden Punkten quadriert +und mit dem gesuchten Ergebnis verglichen. Ist er größer, +wird die Mitte als neue Obergrenze verwendet, andernfalls als neue +Untergrenze. Diese Iteration wird solange fortgesetzt, bis der Fehler +kleiner als der maximal erlaubte ist. +

+ + + + + + + + + +
+ +

+Das Beispielprogramm berechnet das Ergebnis auf etwa 100 Stellen nach +dem Komma. Dieser Wert kann prinzipiell beliebig vergrößert +werden. Zu bedenken ist allerdings, dass dadurch die Laufzeit überproportional +ansteigt. Zwar bleibt die Intervallschachtelung an sich performant, +aber durch die größere Anzahl an zu verarbeitenden Dezimalstellen +benötigt jeder einzelne Aufruf einer arithmetischen Methode mehr +Rechenzeit. Zudem erfordert die höhere Genauigkeit insgesamt +mehr Iterationen, so dass insgesamt das Laufzeitverhalten wohl quadratisch +mit der Genauigkeitsanforderung wachsen dürfte.

+ + + + +
 Hinweis 
+
+


+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3