In Java9 wurde das "BigDecimal # ROUND_ ~" - System endlich zu "@ Deprecated". In Blogs und Einträgen, die "BigDecimal" erklären, wird "BigDecimal # setScale", "BigDecimal # dividieren" usw. mit dem System "BigDecimal # ROUND_ ~" erklärt. Was meinst du? Es ist alles "@ veraltet" in Java 9, oder? Ich habe beschlossen, einen Artikel zu schreiben, weil ich mich in letzter Zeit unwohl fühle.
Zunächst von den Grundlagen.
Es wird im Wesentlichen mit der folgenden Methode generiert.
BigDecimal value = BigDecimal.valueOf(1234.567);//Erzeugung aus einem numerischen System
BigDecimal value = new BigDecimal("1234.567");//Aus einer Zeichenfolge generiert
Verwenden Sie diese, da bereits "0", "1", "10" definiert sind.
BigDecimal.ZERO
BigDecimal.ONE
BigDecimal.TEN
Die Erzeugung aus der Zeichenkette erfolgt durch die Zeichenkette in scale
.
System.out.println(new BigDecimal("1234.567").scale()); // → 3
System.out.println(new BigDecimal("1234.56700").scale());// → 5
Verwenden Sie BigDecimal # valueOf
, um aus einer Zahl (double) zu generieren. Es wäre lächerlich, es mit "neu" zu generieren.
BigDecimal value = new BigDecimal(1234.567);// NG!!Erzeugung aus einem numerischen System
System.out.println(value);// → 1234.5670000000000072759576141834259033203125
ResultSet#getBigDecimal
Wenn Sie von "ResultSet" kommen, gibt es "ResultSet # getBigDecimal". Verwenden Sie diese Option.
BigDecimal value = rs.getBigDecimal("COL");
Das Folgende ist nutzlos, also NG
BigDecimal value = BigDecimal.valueOf(rs.getDouble("COL"));
BigDecimal value = new BigDecimal(rs.getString("COL"));
BigDecimal a = BigDecimal.valueOf(123);
BigDecimal b = BigDecimal.valueOf(456);
// value = a + b
BigDecimal value = a.add(b);
System.out.println(value);// 579
BigDecimal a = BigDecimal.valueOf(123);
BigDecimal b = BigDecimal.valueOf(456);
// value = a - b
BigDecimal value = a.subtract(b);
System.out.println(value);// -333
BigDecimal a = BigDecimal.valueOf(123);
BigDecimal b = BigDecimal.valueOf(456);
// value = a * b
BigDecimal value = a.multiply(b);
System.out.println(value);// 56088
Verwenden Sie "BigDecimal # scaleByPowerOfTen".
BigDecimal src = BigDecimal.valueOf(0.123);
BigDecimal value = src.scaleByPowerOfTen(2);//Hundertfach(10 im Quadrat)
System.out.println(value);// 12.3
Es ist viel sauberer als "src.multiply (BigDecimal.valueOf (100))", und Sie müssen keine Instanz von "100" erstellen.
Verwenden Sie "BigDecimal # negate".
BigDecimal src = BigDecimal.valueOf(123);
BigDecimal value = src.negate();
System.out.println(value);// -123
Bitte hören Sie auf, Folgendes zu schreiben.
BigDecimal value = src.multiply(BigDecimal.valueOf(-1));
import java.math.RoundingMode;
//・ ・ ・
BigDecimal a = BigDecimal.valueOf(123);
BigDecimal b = BigDecimal.valueOf(456);
// value = a / b
BigDecimal value = a.divide(b, 3 /* ← scale */, RoundingMode.HALF_UP /*← Rundung*/);
System.out.println(value);// 0.270
Der folgende Schreibstil ist NG
BigDecimal value = a.divide(b, 3, BigDecimal.ROUND_HALF_UP);
Weitere Informationen zum Rundungsmodus finden Sie unter [unten](# Rundungsmodus).
Es gibt auch eine "BigDecimal # divid" -Methode, die keine "Skala" angibt. Wenn es nicht teilbar ist, tritt eine "ArithmeticException" auf, daher ist es besser, die von "scale" angegebene Version zu verwenden.
Verwenden Sie "BigDecimal # scaleByPowerOfTen".
BigDecimal src = BigDecimal.valueOf(8);
BigDecimal value = src.scaleByPowerOfTen(-2);// 1/100(10-Kariert)
System.out.println(value);// 0.08
import java.math.RoundingMode;
//・ ・ ・
BigDecimal src = BigDecimal.valueOf(123.456);
//Rundung
BigDecimal value = src.setScale(2, RoundingMode.HALF_UP);
System.out.println(value); // → 123.46
//Zusammenfassen
BigDecimal value = src.setScale(2, RoundingMode.UP);
//Kürzen
BigDecimal value = src.setScale(2, RoundingMode.DOWN);
Der folgende Schreibstil ist NG
BigDecimal value = src.setScale(2, BigDecimal.ROUND_HALF_UP);
Weitere Informationen zum Rundungsmodus finden Sie unter [unten](# Rundungsmodus).
BigDecimal#toPlainString
BigDecimal # toString
kann exponentiell sein, daher denke ich, dass es besser ist , BigDecimal # toPlainString
zu verwenden.
BigDecimal value = new BigDecimal("0.0000001");
System.out.println(value.toString()); // → 1E-7
System.out.println(value.toPlainString());// → 0.0000001
Jackson hat auch die Option, "toPlainString" zu verwenden. JsonGenerator.Feature.html#WRITE_BIGDECIMAL_AS_PLAIN
Sowohl "BigDecimal # toString" als auch "BigDecimal # toPlainString" berücksichtigen "scale" in der Zeichenfolge und bleiben auch dann erhalten, wenn auf den Bruch "0" folgt. Wenn Sie dies deaktivieren möchten, verwenden Sie "BigDecimal # stripTrailingZeros". Sie müssen nicht hart mit regulären Ausdrücken arbeiten.
BigDecimal value = new BigDecimal("1.000000");
System.out.println(value); // → 1.000000
System.out.println(value.stripTrailingZeros());// → 1
int
・ long
・ double
BigDecimal value = BigDecimal.valueOf(12345);
int i = value.intValue();
long l = value.longValue();
double d = value.doubleValue();
Es gibt auch float
und BigInteger
.
Es gibt eine Version der Konvertierung in Ganzzahlen, die eine Ausnahme auslöst, wenn Informationen vorliegen, die aus Toleranzgründen verloren gehen. Umgekehrt wird die normale Version ignoriert, auch wenn Informationen verloren gehen.
int i = value.intValueExact();
long l = value.longValueExact();
Es gibt auch "Byte" -, "Short" - und "BigInteger" -Versionen der "-ValueExact" -Methodenfamilie.
Da "BigDecimal # equals" "false" zurückgibt, wenn "scale" nicht übereinstimmt, Wenn Sie ein System schreiben, an dem Sie nicht interessiert sind, z. B. "scale", sollten Sie beurteilen, ob das Ergebnis von "compareTo" mit "0" übereinstimmt.
BigDecimal value1 = new BigDecimal("123.0"); // scale=1
BigDecimal value2 = new BigDecimal("123.00");// scale=2
System.out.println(value1.equals(value2)); // false
System.out.println(value1.compareTo(value2) == 0);// true
BigDecimal # equals
・ BigDecimal # hashCode
berücksichtigt also auch scale
Das Schreiben eines Systems, an dem Sie nicht interessiert sind, wie z. B. "Skala", kann Sie verletzen.
BigDecimal value1 = new BigDecimal("123.0"); // scale=1
BigDecimal value2 = new BigDecimal("123.00");// scale=2
Map<BigDecimal, String> map = new HashMap<>();
map.put(value1, "data");
System.out.println(map.get(value2));// null
In diesem Fall möchten Sie möglicherweise die Skalierung mit BigDecimal # stripTrailingZeros stabilisieren.
BigDecimal value1 = new BigDecimal("123.0"); // scale=1
BigDecimal value2 = new BigDecimal("123.00");// scale=2
Map<BigDecimal, String> map = new HashMap<>();
map.put(value1.stripTrailingZeros(), "data");
System.out.println(map.get(value2.stripTrailingZeros()));// data
RoundingMode
"RoundingMode" wird durch "enum" definiert, und neben "Rundung" gibt es verschiedene Dinge wie "Aufrunden", "Abschneiden", "Runden auf positive Unendlichkeit", "Runden auf negative Unendlichkeit", also einmal javadoc. Ich denke du solltest es überprüfen.
Das Folgende ist eine Transkription von Rounding Mode javadoc.
CEILING Es ist ein Modus zum Rollen, um sich der positiven Unendlichkeit zu nähern. DOWN Dieser Modus rundet auf 0 ab. FLOOR Es ist ein Modus zum Rollen, um sich der negativen Unendlichkeit zu nähern. HALF_DOWN Dies ist ein Rundungsmodus, der auf die "nächste Zahl" rundet (wenn die Zahlen auf beiden Seiten gleich weit entfernt sind, werden sie abgeschnitten). HALF_EVEN Rundungsmodus zum Runden auf die "nächstgelegene Zahl" (wenn jedoch die Zahlen auf beiden Seiten gleiche Abstände haben, auf die gerade Seite runden). HALF_UP Dies ist ein Rundungsmodus, der auf die "nächste Zahl" rundet (wenn jedoch die Zahlen auf beiden Seiten gleich weit entfernt sind, werden sie aufgerundet). UNNECESSARY Ein Rundungsmodus, der anzeigt, dass das Ergebnis der erforderlichen Operation genau ist und keine Rundung erfordert. UP Dieser Modus rundet von 0 ab.
Verwenden Sie nicht das BigDecimal # ROUND_ ~ -System und die Methoden, die deren Verwendung voraussetzen. (@ Veraltet
in Java 9)
Es sollte zwei Methoden geben, die für jede Methode "RoundingMode" verwenden. Verwenden wir also diese.
Die Methode, die in 9 zu "@ Deprecated" wurde, ist ein Erbe der 1.4-Ära. Wenn ich jedoch normalerweise mit "BigDecimal Division" google, bin ich verzweifelt, weil alle Seiten, die "BigDecimal.ROUND_HALF_UP" verwenden, herauskommen.
Recommended Posts