Frage

Kürzlich habe ich versucht, die Verwendung von zu verstehen java.math.MathContext aber nicht richtig verstanden.Wird es zum Aufrunden verwendet? java.math.BigDecimal.Wenn ja, warum werden nicht die Dezimalstellen, sondern sogar der Mantissenteil gerundet?

Aus API-Dokumenten habe ich erfahren, dass es dem in angegebenen Standard entspricht ANSI X3.274-1996 Und ANSI X3.274-1996/AM 1-2000 Spezifikationen, aber ich konnte sie nicht online lesen.

Bitte lassen Sie mich wissen, wenn Sie dazu eine Idee haben.

War es hilfreich?

Lösung

@jatan

Danke für deine Antwort.Es ergibt Sinn.Können Sie mir bitte MathContext im Kontext der BigDecimal#round-Methode erklären?

Daran ist nichts Besonderes BigDecimal.round() vs. irgendein anderes BigDecimal Methode.In allen Fällen ist die MathContext Gibt die Anzahl der signifikanten Ziffern und die Rundungstechnik an.Grundsätzlich besteht jedes aus zwei Teilen MathContext.Es gibt eine Präzision, und es gibt auch eine RoundingMode.

Die Präzision gibt wiederum die Anzahl der signifikanten Stellen an.Also, wenn Sie angeben 123 als Zahl und fragen Sie nach zwei signifikanten Ziffern, die Sie erhalten werden 120.Es könnte klarer sein, wenn Sie in wissenschaftlicher Notation denken.

123 wäre 1.23e2 in wissenschaftlicher Notation.Wenn Sie nur zwei signifikante Ziffern behalten, erhalten Sie 1.2e2, oder 120.Indem wir die Anzahl der signifikanten Ziffern verringern, verringern wir die Genauigkeit, mit der wir eine Zahl angeben können.

Der RoundingMode Teil gibt an, wie wir mit dem Präzisionsverlust umgehen sollen.Um das Beispiel wiederzuverwenden, wenn Sie es verwenden 123 als Zahl eingeben und nach zwei signifikanten Ziffern fragen, haben Sie Ihre Genauigkeit verringert.Mit einem RoundingMode von HALF_UP (der Standardmodus), 123 wird werden 120.Mit einem RoundingMode von CEILING, Du wirst kriegen 130.

Zum Beispiel:

System.out.println(new BigDecimal("123.4",
                   new MathContext(4,RoundingMode.HALF_UP)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(2,RoundingMode.HALF_UP)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(2,RoundingMode.CEILING)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(1,RoundingMode.CEILING)));

Ausgänge:

123.4
1.2E+2
1.3E+2
2E+2

Sie können sehen, dass sowohl die Genauigkeit als auch der Rundungsmodus die Ausgabe beeinflussen.

Andere Tipps

Informationen zum Runden nur des Bruchteils einer BigDecimal-Zahl finden Sie unter BigDecimal.setScale(int newScale, int roundingMode) Methode.

Z.B.Um eine Zahl mit drei Nachkommastellen in eine mit zwei Nachkommastellen zu ändern und aufzurunden:

BigDecimal original = new BigDecimal("1.235");
BigDecimal scaled = original.setScale(2, BigDecimal.ROUND_HALF_UP);

Das Ergebnis ist ein BigDecimal mit dem Wert 1,24 (wegen der Aufrundungsregel)

Ich möchte hier einige Beispiele hinzufügen.Ich habe sie in früheren Antworten nicht gefunden, aber ich finde sie nützlich für diejenigen, die vielleicht irreführen wichtige Ziffer mit Anzahl Nachkommastellen.Nehmen wir an, wir haben einen solchen Kontext:

MathContext MATH_CTX = new MathContext(3, RoundingMode.HALF_UP);

Für diesen Code:

BigDecimal d1 = new BigDecimal(1234.4, MATH_CTX);
System.out.println(d1);

Es ist völlig klar, dass Ihr Ergebnis so ist 1.23E+3 wie die Jungs oben sagten.Die ersten signifikanten Ziffern sind 123...

Aber was ist in diesem Fall:

BigDecimal d2 = new BigDecimal(0.000000454770054, MATH_CTX);
System.out.println(d2);

Ihre Nummer wird nicht auf 3 Stellen nach dem Komma gerundet - Für jemanden ist es möglicherweise nicht intuitiv und es lohnt sich, es hervorzuheben.Stattdessen wird auf gerundet ersten 3 signifikanten Ziffern, die in diesem Fall „4 5 4“ sind.Der obige Code ergibt also 4.55E-7 und nicht drin 0.000 wie jemand erwarten konnte.

Ähnliche Beispiele:

BigDecimal d3 = new BigDecimal(0.001000045477, MATH_CTX);
 System.out.println(d3);  // 0.00100

BigDecimal d4 = new BigDecimal(0.200000477, MATH_CTX);
 System.out.println(d4);   // 0.200

BigDecimal d5 = new BigDecimal(0.000000004, MATH_CTX);
    System.out.println(d5); //4.00E-9

Ich hoffe, dieses offensichtliche, aber relevante Beispiel wäre hilfreich ...

Wenn ich Sie richtig verstehe, hört es sich so an, als würden Sie erwarten, dass der MathContext steuert, wie viele Ziffern nach dem Dezimalpunkt beibehalten werden sollen.Dafür ist es nicht gedacht.Es gibt an, wie viele Ziffern beibehalten werden sollen. gesamt.Wenn Sie also angeben, dass Sie drei signifikante Ziffern wünschen, erhalten Sie nur diese.

Zum Beispiel dies:

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(20)));

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(10)));

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(5)));

wird ausgeben:

1234567890.123456789
1234567890
1.2346E+9

Es ist nicht zum Spaß.Tatsächlich habe ich ein Online-Beispiel gefunden, in dem die Verwendung von angegeben ist MathContext um die in BigDecimal gespeicherten Beträge/Zahlen zu runden.

Zum Beispiel,

Wenn MathContext konfiguriert ist precision = 2 Und rounding mode = ROUND_HALF_EVEN

BigDecimal Number = 0.5294, Ist gerundet Zu 0.53

Deshalb dachte ich, dass es sich um eine neuere Technik handelt und nutzte sie zum Abrunden.Es wurde jedoch zu einem Albtraum, weil es anfing, sogar einen Mentissa-Teil der Zahl zu runden.

Zum Beispiel,

Number = 1.5294 wird auf gerundet 1.5

Number = 10.5294 wird auf gerundet 10

Number = 101.5294 wird auf gerundet 100

....und so weiter

Das ist also nicht das Verhalten, das ich beim Runden erwartet habe (da Präzision = 2).

Es scheint eine gewisse Logik zu haben, denn anhand des Musters kann ich sagen, dass es die ersten beiden Ziffern (da die Genauigkeit 2 ist) der Zahl nimmt und dann Nullen bis zur Nummer anhängt.Anzahl der Ziffern entspricht dem ungerundeten Betrag (sehen Sie sich das Beispiel 101,5294 an ...)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top