Ich verwende Java 8 in meinem Projekt.
Ich codiere in Java, was eine Geldberechnung beinhaltet, und der auf dem Bildschirm angezeigte Wert ist
299.999999999999988897769753748434595763683319091796875000
Ich bin auf ein Ereignis gestoßen, das leicht davon abwich. Ich schäme mich zu sagen, dass ich die Logik geschrieben habe, um den (?) Betrag zum ersten Mal richtig zu berechnen Ich ging weiter, während ich den Grund dafür untersuchte.
In der ersten Stufe der Verarbeitung wird beispielsweise der Betrag mit einem Prozentsatz multipliziert
//Prozentsatz und Menge, die von einem Modell erhalten wurden
double d = 0.3;
BigDecimal bd = new BigDecimal("1000");
//Berechnung
BigDecimal bd2 = bd.multiply(new BigDecimal(d));
System.out.println(bd2); // 299.999999999999988897769753748434595763683319091796875000
Sie haben eine BigDecimal-Instanz erstellt, indem Sie das doppelte Argument an den Konstruktor übergeben haben. Als Ergebnis des Abrufs aus der Datenbank wurde das in der Servive-Klasse verwendete Modellfeld als Doppeltyp definiert.
Obwohl es im Code dezimal definiert ist, wird es intern binär behandelt Werte, die binäre und kreisförmige Brüche sind (z. B. doppelt 0,3), werden gerundet, dh es tritt ein Fehler auf.
durch Bezugnahme
double d = 3.3 / 1.1 //Ich möchte, dass du 3 aber 2 bist.9999999999999996
Ich habe die Referenz vorerst gelesen. https://docs.oracle.com/javase/jp/8/docs/api/java/math/BigDecimal.html
- add - subtract - multiply - divide Führen Sie vier Regeln mit Methoden wie z. Geben Sie im Rundungsmodus Rundung / Rundung / Rundung an. Die Logik war diesmal nicht so kompliziert, also habe ich keine komplizierten Methoden angewendet.
//Instanzgenerierung jedes Mal, ineffizient
BigDecimal b1 = new BigDecimal(10); //Nicht gut
//Verwenden Sie den Cache valueOf()
BigDecimal b2 = BigDecimal.valueOf(10); //gut
//∵ Ein Fehler tritt auf, wenn die Binärzahl ein Kreisbruch ist.
BigDecimal b3 = new BigDecimal(0.3); //Nicht gut
//Aus einer Zeichenfolge generieren
BigDecimal b4 = new BigDecimal("0.3"); //gut
//Wenn Sie den Wert von double in BigDecimal konvertieren möchten
BigDecimal b5 = BigDecimal.valueOf(0.3); //(Ich möchte diese Konvertierung nach Möglichkeit nicht implementieren.)
--BigDecimal # ROUND_xxxx-Serie ist in Java 9 oder höher veraltet. Verwenden wir RoundingMode (Java8 wird im aktuellen Projekt verwendet, aber ich werde mir dessen im Vorgriff auf ein Versions-Upgrade bewusst sein).
http://javazuki.com/articles/bigdecimal-usage.html#_roundingmode https://qiita.com/TKR/items/52635175654b9b818b89
BigDecimal three = BigDecimal.valueOf(3);
BigDecimal five = BigDecimal.valueOf(5);
int hoge = three.compareTo(five); // -1
int piyo = three.compareTo(three); // 0
int fuga = five.compareTo(three); // 1
Recommended Posts