BigDecimal und Berechnungen weiterhin mit + / - usw.

internet

Top Contributor
Hallo,

ich bin gerade dabei BigDecimal zu nutzen (davor habe ich immer nur double oder float) verwendet....
Ich verstehe, dass es Funktionen wie add, multiple etc. gibt.

Gerne möchte ich aber weiterhin mit +, -, / usw. rechnen (jedenfalls bei komplereren Berechnungen), da das sonst ziemlich unübersichtlich wird.
Also anstatt:
Java:
position.getPriceTotalNet().multiply(new BigDecimal(1.00).add(subPosition.getTax().divide(new BigDecimal(100.00)))));

Möchte ich:
Java:
new BigDecimal(subPosition.getPriceTotalNet().doubleValue * (1.00 + (subPosition.getTax().doubleValue / 100.00))));

Ich bin mir nun aber nicht sicher, ob das der richtige Ansatz ist?
 
K

kneitzel

Gast
Also wenn Du eh mit double Werten rechnest und alles immer in double Werte umwandelst: Dann bleib bei double und vergiss BigDecimal.

Wenn Du BigDecimal nutzen willst, dann nutz die Methoden von BigDecimal.

Das ist wie: Du hast ein Tolles Auto, aber das nutzt Du nie, denn die Methoden von Auto willst Du nicht nutzen. Statt dessen möchtest Du auf Deine Beine vertrauen, daher steigst Du immer aus und gehst zu Fuß, wenn Du irgendwo hin willst.
 

internet

Top Contributor
Also wenn Du eh mit double Werten rechnest und alles immer in double Werte umwandelst: Dann bleib bei double und vergiss BigDecimal.

Wenn Du BigDecimal nutzen willst, dann nutz die Methoden von BigDecimal.

Das ist wie: Du hast ein Tolles Auto, aber das nutzt Du nie, denn die Methoden von Auto willst Du nicht nutzen. Statt dessen möchtest Du auf Deine Beine vertrauen, daher steigst Du immer aus und gehst zu Fuß, wenn Du irgendwo hin willst.
Ich möche zu BigDecimal wechseln aus diesem Grund:

Was ich aber nicht möchte, ist, dass ich alle meine bestehenden Rechnungen nun mit den Funktionen abbilden muss.
 

LimDul

Top Contributor
Simple Lösung:
Keine komplexen Berechnungen in eine Zeile sondern in entsprechende Methode auslagern und dort auf mehrere Zeilen splitten.

Denn ganz ehrlich
Java:
new BigDecimal(subPosition.getPriceTotalNet().doubleValue * (1.00 + (subPosition.getTax().doubleValue / 100.00))));
Ist ist auch nicht wirklich lesbar. Ich kann dann nicht wirklich sofort sehen ob das was da berechnet wird, korrekt ist
 

mihe7

Top Contributor
Ich bin mir nun aber nicht sicher, ob das der richtige Ansatz ist?
Nein. Erstens musst Du den Betrag auf 2 Nkst runden und selbst dann erhältst Du z. B. für 0,5 € unterschiedliche Ergebnisse:

Java:
new BigDecimal(0.5 * (1.00 + 19.0/100.0)).setScale(2, BigDecimal.ROUND_HALF_UP)
liefert 0,59, während
Java:
new BigDecimal(0.5).multiply(BigDecimal.ONE.add(new BigDecimal(19).movePointLeft(2))).setScale(2, BigDecimal.ROUND_HALF_UP)
korrekte 0,60 liefert.
 

LimDul

Top Contributor
Nochmal was ausführlicher - ich kann deine Schmerzen durchaus nachvollziehen, ich bin auch in einem Bereich tätig, wo wir Beträge berechnen müssen (und im aktuellen Projekt sind die Berechnungen durchaus komplex). Eine Teilberechnung:

(1+A+i) / (((1-(p + s + g))*(1-r)*(1-f))

Schreibe ich das mit double in eine Zeile ist schon schwer lesbar.
Mit BigDecimal wäre es komplett unleserlich.

Wie sieht es mit BigDecimal aus der Code (bzw. die Klasse heißt bei uns Decimal und ist ein Wrapper um BigDecimal mit ein paar convience Eigenschaften)

Java:
        Decimal dividend = ONE.add(getA()).add(getI());
        Decimal divisorFaktor1 = ONE.subtract(getP().add(getS())
                .add(getG()));
        Decimal divisorFaktor2 = ONE.subtract(getR());
        Decimal divisorFaktor3 = ONE.subtract(getF());
        return getBerechnungsHelper().dividiere(dividend,
                                                divisorFaktor1.multiply(divisorFaktor2).multiply(divisorFaktor3));
Ja, es werden so deutlich mehr Zeilen - dafür ist es aber dann lesbarer

Anmerkung - die Variablen heißen nicht wirklich a,i etc - die haben schon sprechende Namen, aber ich kann hier keinen Business-Code 1:1 reinkopieren :)

Der BerechnungsHelper ist eine Utility-Klasse, die so Sachen wie Rundungen und Genauigkeiten wegkaspelt - wir haben z.B. definiert, dass die internen Berechnungen standardmäßig mit 5 Nachkommastellen und Rundungsmethode X gemacht werden. Und am Ende, der finale Wert wird dann auf 2 Nachkommastellen gerundet. Damit muss ich mir nicht bei jeder Berechnung Gedanken um die Genauigkeit machen, sondern die ist zentral definiert und kann auch zentral angepasst werden.
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Also Java bietet kein operator overloading. Daher kannst Du nicht mit Instanzen von Klassen arbeiten ohne auf die Methoden zu wechseln.
In dem Moment, wo Du die Klasse nicht mehr verwendest und statt dessen die primären Typen von Java verwendest, dann bekommst Du sofort die Nachteile, die Du umgehen wolltest.

Als eine weitere Alternative wäre ggf. noch zu nennen: Nutze statt Java eine Sprache, die Operator Overloading unterstützt. Also z.B. Kotlin (so Du in der JVM bleiben möchtest) oder natürlich C++ und co ...

Aber in Java bleibt es bei dem friss oder stirb: Nutze Klassen mit den Methoden oder nutze die primären Datentypen zusammen mit den Operatoren. Eine andere Möglichkeit hast Du nicht und einen "Tod" musst Du hier "sterben" so Du bei Java bleiben willst.
 

mrBrown

Super-Moderator
Mitarbeiter
Wie ich im anderen Thread schon sagte: du wirst vermutlich irgendwann den BigDecimal in einer extra "Geld"-Klasse kapseln wollen, die dir solche Operationen einfacher macht :) Für Geldbeträge braucht man ja ein anderes Set an Operationen als für "Zahlen".


Um aber auch zu deiner ursprünglichen Formel was zu sagen: Prozentwerte wie zB "19%" speichert man sinnvollerweise nicht als 19, sondern als 0.19 – das ist der mathematische Wert dahinter, die "19%" sind nur eine einfache Darstellung für Menschen.

Wenn man die Rechnung dann noch etwas auseinander zieht, sieht das dann etwa so aus:
Java:
var totalTax = position.getPriceTotalNet().multiply(subPosition.getTax());
var totalPrice = position.getPriceTotalNet().add(totalTax);

was schon mal deutlich schöner aussieht, vor allem wenn man es noch in einer sinnvoll benannten Methode kapselt :)

.divide(new BigDecimal(100.00))
Ersetzen durch .movePointLeft(2).
Ich bin ehrlich überrascht, dass du movePointLeft leserlicher findest als divide 😅
 

CSHW89

Bekanntes Mitglied
Um auch nochmal Senf dazuzugeben, falls dir die Kommastellen nach den Centstellen (also Bruchteile von Cents) egal sind, würde ich darauf zurückgreifen, Geldbeträge in Cent als int zu speichern. Wie gesagt, funktioniert nur, wenn Bruchteile von Cents in einer Operation auf Cents gerundet werden darf:
Java:
int betrag = 2199;  // 21,99€
int brutto = (int) Math.round(betrag * 1.19);  // 26,17€
Centbeträge werden dadurch zumindest immer genau gespeichert.
 

mrBrown

Super-Moderator
Mitarbeiter
Um auch nochmal Senf dazuzugeben, falls dir die Kommastellen nach den Centstellen (also Bruchteile von Cents) egal sind, würde ich darauf zurückgreifen, Geldbeträge in Cent als int zu speichern. Wie gesagt, funktioniert nur, wenn Bruchteile von Cents in einer Operation auf Cents gerundet werden darf:
Alternativ zehntel oder Hundertstel Cent zum Rechnen nutzen, je nachdem wie viele Nachkommastellen man bracht. @internet fand Rechnen mit Cents allerdings doof :)
 

temi

Top Contributor
Alternativ zehntel oder Hundertstel Cent zum Rechnen nutzen, je nachdem wie viele Nachkommastellen man bracht. @internet fand Rechnen mit Cents allerdings doof :)
Man könnte diese Funktionalitiäten auch in einer eigenen Klasse verpacken, aber dann sind wir wieder fast am Anfang und bei der Antwort auf eine Frage des TE aus dem anderen Thema:
Es gibt bereits extra Typen für Geld, zB mit JavaMoney
Was genau meinst du mit nachbasteln?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Output BigDecimal anstatt double / Problem beim Rechnen Java Basics - Anfänger-Themen 16
D BigDecimal Ausgabe sehr lang. Java Basics - Anfänger-Themen 2
B TableView: laufender Saldo mit BigDecimal? Java Basics - Anfänger-Themen 6
I BigDecimal als Parameter verwenden Java Basics - Anfänger-Themen 3
Joker4632 Klassen BigDecimal Multiplikation liefert nicht erwarteten Wert Java Basics - Anfänger-Themen 6
A Kaufmännisches Runden mit BigDecimal Java Basics - Anfänger-Themen 14
G Compiler-Fehler BigDecimal Java Basics - Anfänger-Themen 5
AssELAss Datentypen BigDecimal Vergleichen ob Ergebnis >= 200 Java Basics - Anfänger-Themen 5
AssELAss Über ein Objekt vom Typ BigDecimal iterieren Java Basics - Anfänger-Themen 6
I BigDecimal < 0 Java Basics - Anfänger-Themen 12
E BigDecimal PQ Formel Java Basics - Anfänger-Themen 16
H DecimalFormat mit BigDecimal? Java Basics - Anfänger-Themen 6
K Wurzelberechnung Newton BigDecimal Java Basics - Anfänger-Themen 2
W BigDecimal bei Rechnungen Java Basics - Anfänger-Themen 5
neurox BigDecimal setScale wird ignoriert Java Basics - Anfänger-Themen 2
N max(BigDecimal,BigDecimal) Java Basics - Anfänger-Themen 2
P Mit double und BigDecimal rechnen Java Basics - Anfänger-Themen 6
M JTable Spalte ist bigDecimal Java Basics - Anfänger-Themen 2
G BigDecimal -- exception Java Basics - Anfänger-Themen 3
G BigDecimal mit zwei Nachkommastellen darstellen Java Basics - Anfänger-Themen 2
H integer 2 bigdecimal ? Java Basics - Anfänger-Themen 2
A Problem mit BigDecimal? Java Basics - Anfänger-Themen 3
G sehr kleine Dezimalzahlen (BigDecimal) falsch angezeigt Java Basics - Anfänger-Themen 5
B BigDecimal Java Basics - Anfänger-Themen 6
B String to BigDecimal Java Basics - Anfänger-Themen 3
T Wissenschaftliche Notationen + BigDecimal Java Basics - Anfänger-Themen 5
T zwei BigDecimal vergleichen Java Basics - Anfänger-Themen 2
B Frage zu BigDecimal! dringend Java Basics - Anfänger-Themen 2
D mehrere Berechnungen in einer Methode Java Basics - Anfänger-Themen 9
S Geometrische Berechnungen Java Basics - Anfänger-Themen 6
U Array werte speichern und für berechnungen nutzen Java Basics - Anfänger-Themen 4
N Mehrere berechnungen auf einem Button legen? Java Basics - Anfänger-Themen 19
S Berechnungen Java Basics - Anfänger-Themen 13
S Konsole für längere Berechnungen anzeigen als Statusanzeige Java Basics - Anfänger-Themen 4
C Konstanten zu einfachen Berechnungen unterhalb Main Methode Java Basics - Anfänger-Themen 19
F date und time berechnungen Java Basics - Anfänger-Themen 2
M Programm für trigonometrische Berechnungen in 84 Fällen. Java Basics - Anfänger-Themen 12
S Bearbeitungsreihenfolge bei Berechnungen Java Basics - Anfänger-Themen 8
S Benutzung von Thread -> Trennung GUI und Berechnungen &lt Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben