Was ich möchte, ist eine Methode zum Konvertieren eines Double in eine Zeichenfolge, die mit der Hälfte-up-Methode rundet - d.h. wenn die Dezimalzahl zu runden ist 5, es rundet immer auf die nächste Zahl. Dies ist die Standard-Rundungsmethode, die die meisten Menschen in den meisten Situationen erwarten.
Außerdem möchte ich, dass nur signifikante Ziffern angezeigt werden, d. h. es sollten keine Nullen am Ende stehen.
Ich weiß, dass eine Methode, dies zu tun, die Verwendung der Methode "String.format" ist:
String.format("%.5g%n", 0.912385);
gibt zurück:
0.91239
was toll ist, aber es zeigt immer Zahlen mit 5 Dezimalstellen an, auch wenn sie nicht signifikant sind:
String.format("%.5g%n", 0.912300);
gibt zurück:
0.91230
Eine andere Methode ist die Verwendung des DecimalFormatter
:
DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);
gibt zurück:
0.91238
Wie Sie sehen können, wird hier jedoch halbgerade gerundet. Das heißt, es wird abgerundet, wenn die vorherige Ziffer gerade ist. Was ich möchte, ist dies:
0.912385 -> 0.91239
0.912300 -> 0.9123
Wie kann ich das am besten in Java erreichen?
Verwenden Sie setRoundingMode
, setzen Sie RoundingMode
explizit, um Ihr Problem mit der halbgeraden Runde zu behandeln, und verwenden Sie dann das Formatmuster für Ihre gewünschte Ausgabe.
Beispiel:
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
Double d = n.doubleValue();
System.out.println(df.format(d));
}
ergibt die Ausgabe:
12
123.1235
0.23
0.1
2341234.2125
EDIT: In der ursprünglichen Antwort wird nicht auf die Genauigkeit der doppelten Werte eingegangen. Das ist in Ordnung, wenn es Ihnen egal ist, ob auf- oder abgerundet wird. Wenn Sie jedoch eine genaue Rundung wünschen, müssen Sie die erwartete Genauigkeit der Werte berücksichtigen. Fließkommawerte haben intern eine binäre Darstellung. Das bedeutet, dass ein Wert wie 2,77395 intern nicht genau diesen Wert hat. Er kann etwas größer oder etwas kleiner sein. Wenn der interne Wert etwas kleiner ist, wird er nicht auf 2,7740 aufgerundet. Um hier Abhilfe zu schaffen, müssen Sie sich über die Genauigkeit der Werte, mit denen Sie arbeiten, im Klaren sein und diesen Wert vor dem Runden addieren oder subtrahieren. Wenn Sie z. B. wissen, dass Ihre Werte bis auf 6 Stellen genau sind, dann addieren Sie diese Genauigkeit zum Wert, um die Hälfte der Werte aufzurunden:
Double d = n.doubleValue() + 1e-6;
Um abzurunden, subtrahieren Sie die Genauigkeit.
Angenommen, Wert
ist ein Double
, können Sie tun:
(double)Math.round(value * 100000d) / 100000d
Das ist für eine Genauigkeit von 5 Ziffern. Die Anzahl der Nullen gibt die Anzahl der Nachkommastellen an.
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;