Output BigDecimal anstatt double / Problem beim Rechnen

internet

Top Contributor
Ich bin gerade dabei eine Methode anstatt einem double einen BigDecimal zu verwenden.
Gerundet soll werden nach:

RoundingMode.HALF_EVEN
Scale = 6


LocalDateTime tempDate = 2020-11-13T00:00;
Local updateDate = 2020-11-14T11:06;
int totalMonths = 3;

Java:
long totalMinutes = Duration.between(tempDate, updateDate).toMillis() / 1000;
        long maxMinutes = YearMonth.of(tempDate.getYear(), tempDate.getMonthValue()).lengthOfMonth() * 24 * 60 * 60;
        result = (((double) totalMonths) / 12)
                + (((double) totalMinutes) / ((double) maxMinutes)
                        / 12));

Habe folgendes probiert:
Java:
BigDecimal c1 = (new BigDecimal(totalMonths)).divide(new BigDecimal(12), 6, RoundingMode.HALF_EVEN);
BigDecimal c2 = new BigDecimal(totalMinutes).divide(new BigDecimal(maxMinutes), 6, RoundingMode.HALF_EVEN);
BigDecimal c3 = new BigDecimal(12);
       
BigDecimal test = ((c1).add(c2)).divide(c3, 6, RoundingMode.HALF_EVEN);

Herauskommen soll: 0.2540625 (laut double)
Rausbekommen tue ich aber: 0.024896

Anschließend würde ich gerne den oberen Wert von 1 abziehen also:
Java:
double usedValue = Wert von oben;
result = 1-usedValue;

Womit dann 0.745937 rauskommen soll.

Jemand eine Idee, was ich falsch mache?
 

Robert Zenz

Top Contributor
Java:
long totalMinutes = Duration.between(tempDate, updateDate).toMillis() / 1000;

Millisekunden dividiert durch tausend ergibt Sekunden, nicht Minuten.
 

Robert Zenz

Top Contributor
Java:
long maxMinutes = YearMonth.of(tempDate.getYear(), tempDate.getMonthValue()).lengthOfMonth() * 24 * 60 * 60;

Und das sind Sekunden, nicht Minuten...und deine "double" Logik kuerzt sich auf:

Java:
result = (totalMonths / 12) + (totalMinutes / maxMinutes / 12);

Und da ist irgendwie eine Klammer zu viel.
 

Robert Zenz

Top Contributor
Du hast geschrieben dass die Ergebnisse zwischen "double" und "BigDecimal" unterschiedlich sind...und deine Logiken sind unterschiedlich, in etwa um den Faktor 10. Deswegen hast du da ein unterschiedliches Ergebnis.
 

internet

Top Contributor
Du hast geschrieben dass die Ergebnisse zwischen "double" und "BigDecimal" unterschiedlich sind...und deine Logiken sind unterschiedlich, in etwa um den Faktor 10. Deswegen hast du da ein unterschiedliches Ergebnis.
wo meinst du, dass die Logik unterschiedlich ist:

Java:
  double result = (((double) totalMonths) / 12) + (((double) totalMinutes) / ((double) maxMinutes)/ 12);

Java:
    BigDecimal c1 = (new BigDecimal(totalMonths)).divide(new BigDecimal(12), 6, CalculateFunctions.ROUNDING_MODE);
        BigDecimal c2 = new BigDecimal(totalMinutes).divide(new BigDecimal(maxMinutes), 6, CalculateFunctions.ROUNDING_MODE);
        BigDecimal c3 = new BigDecimal(12);       
        BigDecimal result = ((c1).add(c2)).divide(c3, 6, CalculateFunctions.ROUNDING_MODE);

long totalMinutes und long maxMinutes nehme ich ja beides mal das gleiche...
 

Robert Zenz

Top Contributor
Ja, genau da.

Java:
double result = (((double) totalMonths) / 12) + (((double) totalMinutes) / ((double) maxMinutes)/ 12);
BigDecimal result = ((c1).add(c2)).divide(c3, 6, CalculateFunctions.ROUNDING_MODE);

Vereinfacht:

Java:
double result = (totalMonths / 12) + ( totalMinutes / maxMinutes / 12);
BigDecimal result = c1.add(c2).divide(c3);
 

internet

Top Contributor
Ne, das stimmt etwas nicht...
Java:
double result1 = (totalMonths / 12) + ( totalMinutes / maxMinutes / 12);

Hier bekomme ich 0 raus, der Wert ist aber: 0.2540625 (und der ist korrekt)
 

Robert Zenz

Top Contributor
Ja, weil ich es vereinfacht habe um dir zu zeigen dass die Klammernsetzung falsch ist. Du dividierst durch zwoelf und addierst dann, im Gegensatz zu "BigDecimal", wo du addierst und dann dividierst.
 

internet

Top Contributor
Ja, weil ich es vereinfacht habe um dir zu zeigen dass die Klammernsetzung falsch ist. Du dividierst durch zwoelf und addierst dann, im Gegensatz zu "BigDecimal", wo du addierst und dann dividierst.
wie gesagt, die obere Kalkulation double ist richtig:
Java:
result = (((double) totalMonths) / 12) + (((double) totalMinutes) / ((double) maxMinutes) / 12));
= 0.2540625

Bei der Vereinfachung:
Java:
double result1 = (totalMonths / 12) + ( totalMinutes / maxMinutes / 12);
= 0

Ich möchte als BigDecimal ebenfalls die 0.2540625
 

temi

Top Contributor
Edit: Hier dein Code mit BigDecimal
Java:
BigDecimal c1 = (new BigDecimal(totalMonths)).divide(new BigDecimal(12), 6, CalculateFunctions.ROUNDING_MODE);
BigDecimal c2 = new BigDecimal(totalMinutes).divide(new BigDecimal(maxMinutes), 6, CalculateFunctions.ROUNDING_MODE);
BigDecimal c3 = new BigDecimal(12);
BigDecimal result = ((c1).add(c2)).divide(c3, 6, CalculateFunctions.ROUNDING_MODE);

Vereinfacht:

c1 = totalMonths / 12
c2 = totalMinutes / maxMinutes
result = (c1 + c2) / 12 <== die Klammerung ergibt sich aus c1.add(c2) und das Ergebnis daraus wird durch 12 dividiert

c1 und c2 eingesetzt:

result = ( (totalMonths / 12) + (totalMinutes / maxMinutes) ) / 12 <== beachte das die Addition vor der Division ausgeführt wird

vs. dem Code mit double

result = (totalMonths / 12) + ( totalMinutes / maxMinutes / 12) <== hier werden erst die Divisionen und dann die Addition ausgeführt

Edit: Warum rundest du dreimal?
 
Zuletzt bearbeitet:

internet

Top Contributor
Java:
BigDecimal c1 = (new BigDecimal(totalMonths)).divide(new BigDecimal(12), 6, CalculateFunctions.ROUNDING_MODE);
BigDecimal c2 = new BigDecimal(totalMinutes).divide(new BigDecimal(maxMinutes), 6, CalculateFunctions.ROUNDING_MODE);
BigDecimal c3 = new BigDecimal(12);  
BigDecimal result = ((c1).add(c2)).divide(c3, 6, CalculateFunctions.ROUNDING_MODE);
hier bekomme ich dann aber das raus: 0.024896 :rolleyes:
 
K

kneitzel

Gast
Was das ganz deutlich zeigt: der Code ist so unleserlich, dass du ihn selbst nicht mehr richtig lesen kannst.

Diesen Zustand musst du ändern!

Und um das richtig zu stellen: Du willst erst c2 / c3 rechnen und das Ergebnis dann zu c1 addieren ...

Also c1.add(c2.divide(c3)) um es einmal deutlich zu schreiben. Aber wenn Du es nicht lesen kannst, dann musst Du es weiter unterteilen, also von mir aus:
c4 = c2.divide(c3)
result = c1.add(c4)
oder so ...

Und c1, c2, c3, ... sind Namen, die Du dir abgewöhnen musst. Was berechnest Du da? Was wird da summiert? Etwas sinnvollere Namen helfen auch dabei, Code lesbar zu machen!
 
K

kneitzel

Gast
Evtl. ein paar kleine Hinweise bezüglich Lesbarkeit:
Das Unterteilen auf mehrere Zeilen hast Du ja schon selbst etwas gemacht. Dabei fällt aber massiv auch die Menge der verwendeten Klammern auf... Die machen es extrem unleserlich.

Hier hilft dann teilweise:
a) Natürlich ein fundiertes Wissen von Java so dass man weiss, wo ein Cast notwendig ist und wo nicht und dann auch, wo welche Klammer unnötig ist. So läßt sich ein Ausdruck wie der bei der Berechnung mit double schon deutlich verbessern.
b) Ausdruck über mehrere Zeilen kann helfen (Hier sehe ich das aber nicht wirklich). Du hast also sowas wie f1(a1, a2) wobei a1 und a2 Ausdrücke sind, die evtl. nicht ganz so übersichtlich sind. Das kann mann dann schreiben als
Java:
f1(
    a1,
    a2
);
Die Ausdrücke a1 und a2 sind dann jeweils auf einer eigenen Zeile und sind so als Einheit zu erkennen.

Aber das wirklich wichtige Hilfsmittel:
c) Unterteile in Methoden. Also Monate durch 12 sind Jahre -> Das kann in eine Methode...
Java:
BigDezimal berechneJahreAusMonaten(final long monate) {
    return new BigDezimal(monate).divide(BigDezimal.valueOf(12), 6, CalculateFunctions.ROUNDING_MODE);
}
Bei dem Rest, weiss ich nicht, was Du da genau berechnest ... aber da muss ja auch irgendwie Jahre rauskommen, denn Du addierst das ja ... Aber egal - mir geht es nicht um Deine Logik sondern nur um Hinweise zum lesbar machen ...

Am Ende solltest Du kurze Methoden haben, die gut lesbar sind. Dann steht da etwas wie:
Java:
berechneWasAuchImmer(final long monate, final long minuten, final long maxMinuten) {
    return berechneJahreAusMonaten(monate).add(berechneJahreAusMinutenUndMaxMinuten(minuten, maxMinuten));
}
Das nur also Beispiel ... bei den Namen fehlt mir jeder Bezug zu dem Kontext, in dem Du bist. Aber vielleicht ist das ja deutlich geworden...

So extrem kurz muss es auch nicht bleiben. Aber es muss immer deutlich sein:
Java:
public void starteAuto(final Schluessel schluessel) {
    zuendschloss.add(schluessel);
    if (!schaltung.istInNeutralerStellung()) {
        schaltung.schalteNeutraleStellung();
    }
    
    zuendschloss.zuendungEin();
    checkKontrollleuchten();
    zuendschloss.anlasserLeuft();
    warteMotorStartOderTimeout();
    zuendschloss.zuendungEin();
}

Sowas kann man dann doch gut lesen, oder? Da sind dann auch Fehler leichter zu finden.Und etwas in der Art sollte durchaus das Ziel sein.

Das einfach nur als kleine Erläuterung. Mit der bin ich weiter sehr grob und oberflächig geblieben, aber ich hoffe, dass es etwas hilft, die Richtung, in die es sich etwas entwickeln sollte, zu verstehen.
 

Neumi5694

Top Contributor
Wie wär's denn, wenn du die Berechnung in eine Methode packst, dann genau die gleiche Methode (identischer Code) für den anderen Datentyp erstellst.
Dann musst du gegebenenfalls nur noch beim Aufruf casten.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
emreiu Formatiertes Output bei Insertion Sort Java Basics - Anfänger-Themen 6
Kotelettklopfer Output korrekt trotz falschem Lösungsweg !? Java Basics - Anfänger-Themen 99
B Output Java Basics - Anfänger-Themen 1
J Fragen zu Input/Output Java Basics - Anfänger-Themen 3
O Input/Output newbile und keine Ahnung! Java Basics - Anfänger-Themen 16
K output Java Basics - Anfänger-Themen 3
Harlequin Compiler-Fehler Text Adventure - "Long Output" Fehler Java Basics - Anfänger-Themen 3
E 2 Matrizen multiplizieren - Output fehlt... Java Basics - Anfänger-Themen 5
A Input/Output Prozess Output genauso in der Konsole ausgeben Java Basics - Anfänger-Themen 0
J Input/Output Den zweiten Output erst nach Eingabe ausgeben Java Basics - Anfänger-Themen 4
A Erste Schritte Java Output wird nicht angezeigt Java Basics - Anfänger-Themen 7
GoldenShadow Input/Output Verschiedene Versionen von Input/Output Java Basics - Anfänger-Themen 3
K cmd output.txt Java Basics - Anfänger-Themen 5
T Output in CMD anzeigen lassen? Java Basics - Anfänger-Themen 1
D Runtime exec output wiedergeben Java Basics - Anfänger-Themen 1
B Input/Output output Datenstrom filtern Java Basics - Anfänger-Themen 0
J Möchte gern den Konsolen Output auf JTextPane umleiten Java Basics - Anfänger-Themen 4
fLooojava Output in einer Textarea einfärben Java Basics - Anfänger-Themen 7
fLooojava OOP Übergabe/Output in Textfield Java Basics - Anfänger-Themen 4
E Input/Output convert string to two dimensional char and output = matrix Java Basics - Anfänger-Themen 2
S Output Problem Java Basics - Anfänger-Themen 2
O OOP Input & Output in der GUI-Programmierung Java Basics - Anfänger-Themen 2
C Input & Output Frage Java Basics - Anfänger-Themen 4
E Input & Output Problem Java Basics - Anfänger-Themen 7
F Input/Output Falsches Output in Datei! Java Basics - Anfänger-Themen 4
G Output aus fremden Klasse auswerten Java Basics - Anfänger-Themen 8
C Input/Output Dynamischer Output von Arrays Java Basics - Anfänger-Themen 3
P Windows vs. Ubuntu verschiedener Output Java Basics - Anfänger-Themen 31
L Output mit zwei ungleichen Strings Java Basics - Anfänger-Themen 17
B In- und Output von XML-Daten in und aus einem Objekt Java Basics - Anfänger-Themen 6
M Input/Output JAXB XML Output von Objekt-Listen? Java Basics - Anfänger-Themen 2
S Compiler-Fehler see the compiler error output Java Basics - Anfänger-Themen 6
S Input/Output Data-Input/Output-Stream Java Basics - Anfänger-Themen 2
B Threads Methoden mit Output in Threads verpacken Java Basics - Anfänger-Themen 4
A Input/Output Taskmanager Output Java Basics - Anfänger-Themen 2
T Objekt Output zu String Array Java Basics - Anfänger-Themen 4
M Output Input im Cmd Fenster Java Basics - Anfänger-Themen 7
T Output in File funktioniert nicht Java Basics - Anfänger-Themen 3
B Limit console output in Eclipse Java Basics - Anfänger-Themen 6
T Java Output File Gliedern Java Basics - Anfänger-Themen 5
P Output einer anderen Anwendung verwenden Java Basics - Anfänger-Themen 7
D Input Output Java Basics - Anfänger-Themen 8
N Verschiedene Input/Output Klassen Java Basics - Anfänger-Themen 3
L StdIn Stdout / Input Output Aufgabe Java Basics - Anfänger-Themen 3
G Output Fehler. Java Basics - Anfänger-Themen 20
M Input/Output Stream aus einem String Java Basics - Anfänger-Themen 2
J IO Frage Hex-Output - Anfängerfrage Java Basics - Anfänger-Themen 5
M Datei Output als Append Java Basics - Anfänger-Themen 3
B Output window grabben? Java Basics - Anfänger-Themen 3
S printable ASCII output erzeugen Java Basics - Anfänger-Themen 3
J File Input/Output und Applet Java Basics - Anfänger-Themen 2
D BigDecimal Ausgabe sehr lang. Java Basics - Anfänger-Themen 2
I BigDecimal und Berechnungen weiterhin mit + / - usw. Java Basics - Anfänger-Themen 11
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
R App soll selbstständig reagieren, anstatt via Models Java Basics - Anfänger-Themen 0
T jOptionPane zum schließen von Fenster, wie "Ja" und "Nein" anstatt Yes und No Java Basics - Anfänger-Themen 2
I Format Problem mit Wert - bekomme 0,10 anstatt 10,00 Java Basics - Anfänger-Themen 6
P Hashmap anstatt LinkedList? Java Basics - Anfänger-Themen 6
T GUI anstatt Bild schwarzes Rechteck gespeichert Java Basics - Anfänger-Themen 0
U buttonarray[this] anstatt buttonarray[index] ? Java Basics - Anfänger-Themen 12
M Anstatt 1 int Rückgabewert, mehrere Rückgaben mit Arraylist Java Basics - Anfänger-Themen 8
J Array anstatt Begriffe als Indizes Java Basics - Anfänger-Themen 14
I Erste Schritte while anstatt for, if und break Java Basics - Anfänger-Themen 10
K Was benutzen anstatt this? Java Basics - Anfänger-Themen 9
K Polymorphie Objektreferenz als Superklasse anstatt des Objekttypes Java Basics - Anfänger-Themen 12
B List list - anstatt ArrayList list = new ArrayList Java Basics - Anfänger-Themen 10
D JTextField anstatt Jbuttons Java Basics - Anfänger-Themen 9
A POI Einlesen Excel Workbook aus BLOB oder von URL anstatt aus Filesystem ? Java Basics - Anfänger-Themen 3
P (Arbeitstag-) Calendar - 9 anstatt 24 Stunden Java Basics - Anfänger-Themen 12
dl85hej Zeitsitschleife anstatt Timer Java Basics - Anfänger-Themen 5
B String.equals(Object) anstatt "=" Java Basics - Anfänger-Themen 3
Horst79 Temp Datei cachen anstatt physikalische Datei im root Verz? Java Basics - Anfänger-Themen 8
G start-oder paint-Methode anstatt Event-Handling-Methode? Java Basics - Anfänger-Themen 3
S StringBuffer anstatt += Java Basics - Anfänger-Themen 8
C Servlets: doPost() etc. anstatt service() Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben