1. Einführung
Um die Wörter aus dem Buch "Effactive Java" auszuleihen, sind die Hauptdesignziele von Float und Doppeltypen für wissenschaftliches Computing und Engineering Computing. Sie führen binäre Schwimmpunktoperationen durch, die sorgfältig so konzipiert sind, dass sie eine genauere schnelle Näherung über den numerischen Bereich in großem Umfang bieten. Sie liefern jedoch keine vollständig genauen Ergebnisse und sollten nicht in Situationen verwendet werden, in denen genaue Ergebnisse erforderlich sind. Kommerzielle Berechnungen erfordern jedoch häufig genaue Ergebnisse, und BigDecimal ist zu diesem Zeitpunkt nützlich.
2. Einführung in BigDecimal
BigDecimal besteht aus einem ganzzahligen nicht-skalischen Wert jeder Präzision und einer 32-Bit-Ganzzahl-Skala. Wenn es Null oder positiv ist, ist die Skala die Anzahl der Ziffern nach dem Dezimalpunkt. Wenn es sich um eine negative Zahl handelt, multiplizieren Sie den nicht skalierenden Wert der Zahl mit einer negativen Skalierungsleistung von 10. Daher ist der von BigDecimal dargestellte Wert (unellkalierter Wert × 10).
3. Testcode
3.1 Konstruktor (Die Haupttest -Parametertypen sind zwei häufige Konstruktoren mit Doppel und String)
Die Codekopie lautet wie folgt: BigDecimal adouble = new BigDecimal (1,22);
System.out.println ("Konstrukt mit einem Doppelwert:" + adouble);
BigDecimal Astring = New BigDecimal ("1,22");
System.out.println ("Konstrukt mit einem Stringwert:" + adstring);
Was ist Ihrer Meinung nach die Ausgabe? Wenn Sie nicht der Meinung sind, dass der erste 1,22 ausgibt, herzlichen Glückwunsch zu der Antwort korrekt. Das Ausgabeergebnis lautet wie folgt:
Kopieren Sie den Code wie folgt: Konstrukt mit einem Doublevalue: 1.219999999999999999733546474089962430298328399658203125
Konstruktieren Sie mit einem Zeichenfolgenwert: 1.22
Beschreibung von JDK:
1. Die Ergebnisse der Konstruktionsmethode mit dem Parametertyp -Doppel sind unvorhersehbar. Einige Leute denken vielleicht, dass das BigDecimal, das durch das Schreiben von Newbigdecimal (0,1) in Java geschrieben wurde, genau 0,1 (Nicht-Scaling-Wert 1, dessen Skala 1 beträgt) entspricht, aber tatsächlich gleich 0,1000000000000000000000555511512312578270211815834545415625 ist. Dies liegt daran, dass 0,1 nicht als doppeltes ausgedrückt werden können (oder für diesen Fall nicht als Binärdezimal für endliche Länge ausgedrückt werden kann). Auf diese Weise beträgt der in die Konstruktionsmethode übergebene Wert nicht genau 0,1 (obwohl er diesem Wert gleich ist).
2. Andererseits ist die String -Konstruktionsmethode vollständig vorhersehbar: Das Schreiben von NewbigDecimal ("0,1") erzeugt ein BigDecimal, das genau gleich dem erwarteten 0,1 entspricht. Im Vergleich dazu wird im Allgemeinen empfohlen, zuerst den String Constructor zu verwenden.
3. Wenn das Doppel als Quelle von BigDecimal verwendet werden muss, beachten Sie bitte, dass dieser Konstruktor eine genaue Konvertierung bietet. Es liefert nicht dasselbe Ergebnis wie die folgenden Operationen: Verwenden Sie zunächst die Double.ToString -Methode (Double) und verwenden Sie dann den BigDecimal (String) -Konstruktor, um das Doppel in die String umzuwandeln. Um das Ergebnis zu erhalten, verwenden Sie die statische ValueOF -Methode (doppelt).
3.2 Zusatzbetrieb
Die Codekopie lautet wie folgt: BigDecimal a = new BigDecimal ("1,22");
System.out.println ("Konstrukt mit einem Stringwert:" + a);
BigDecimal B = neuer BigDecimal ("2,22");
A.Add (b);
System.out.println ("Aplus B ist:" + a);
Es ist leicht zu glauben, dass es ausgeben wird:
Kopieren Sie den Code wie folgt: Konstrukt mit einem StringValue: 1.22
A Plus B ist: 3.44
Aber in der Tat ist A plus b: 1.22
4. Quellcodeanalyse
4.1 ValueOF (Doubleval) Methode
Kopieren Sie den Code wie folgt: public static bigDecimal valueof (Double Val) {
// Erinnerung: Ein Null -Double -Rendit
// die Konstante Null verwenden. Dies könnte wichtig genug sein, um
// einen Fabrikansatz, einen Cache oder einige private Begründung rechtfertigen
// Konstanten später.
returnNew BigDecimal (Double.ToString (Val)); // Siehe den dritten Punkt in 3.1 zur JDK -Beschreibung
}
4.2 Methode (BigDecimal Augend)
public bigDecimal add (BigDecimal Augend) {long xs = this.intcompact; // BigDecimal wird durch eine ganzzahlige Zahl dargestellt, zum Beispiel einen intCompact -Wert von 122 long ys = aug.intcompact; // gleich wie oben biginteger fst = (this.intcompact! ! = Aufgeblasen)? NULL: Augend.intval; int rscale = this.scale; // Die Dezimalstellen long sdiff = (long) rscale - augend.scale; // Der Unterschied zwischen Dezimalstellen, wenn (sdiff! rscale = aug.scale; if (xs == aufgeblasen || (xs = longmultiPlypoWerten (xs, erhöhen)) == aufgeblasen) fst = bigmultiPlypoWerten (erhöhen); } else {int Raise = augend.ChecksCale (SDIFF); if (ys == aufgeblasen || (ys = longmultiplypoWerten (ys, erhöhen)) == aufgeblasen) snd = augend.bigmultiplypoWerten (raise); }} if (xs! = aufgeblasen && ys! = aufgeblasen) {long sum = xs + ys; if ((((sum ^ xs) & (sum ^ ys)))> = 0l) // Beurteilen Sie, ob es einen Überlauf gibt. Return BigDecimal.Valueof (sum, rcale); // Return BigDecimal -Instanz, die mit der statischen Fabrikmethode von BigDecimal erhalten wurde} if (fst == null) fst = biginTeger.valueof (xs); // Bigintiers statische Factory -Methode (snd == null) snd = bigd = bigd = bigd = Snd = Bigd = Bigd = Snd = Bigd = Snd = Snd = Snd = Snd = Snd =). BigInteger sum = fst.add (SND); return (fst.Signum == Snd.Signum)? Neues Bigdecimal (Sum, aufgeblasen, rcale, 0): Neues BigDecimal (SumDas obige ist nur eine Analyse des Additionsquellencode. Subtraktion, Multiplikation und Division geben tatsächlich ein neues BigDecimal -Objekt zurück. Da Biginteger und Bigdecimal beide unveränderlich sind, wird ein neues Objekt bei der Ausführung jeder Betriebsschritt erzeugt, also A.Add (b); Obwohl der Additionsvorgang durchgeführt wird, speichert A den Wert nach dem Additionsvorgang nicht. Die korrekte Verwendung sollte a = a.add (b) sein;
5. Zusammenfassung
(1) Kommerzielle Berechnungen verwenden BigDecimal.
(2) Versuchen Sie, Konstruktoren mit einer String von Parametertyp zu verwenden.
(3) BigDecimals sind unveränderlich. Bei der Durchführung jedes Betriebsschrittes wird ein neues Objekt generiert. Bei der Durchführung von Addition, Subtraktion, Multiplikation und Teilung müssen Sie daher den Wert nach dem Vorgang speichern.
(4) Wir neigen häufig dazu, einige Implementierungsdetails des zugrunde liegenden JDK zu ignorieren, was zu Fehlern führt. Daher müssen wir mehr Aufmerksamkeit schenken.
Referenz: Klasse BigDecimal