samet22
Goto Top

Java wie runde ich richtig - wo ist der Fehler?

Hallo Leute,

Wenn ich Mathematisch runden würde was wäre dann die Rundung auf 2 Nachkommastellen von der Zahl 319.94499999999994 ?

Mein Problem:

double x = (Math.round(319.94499999999994 * 100.0) / 100.0);
Rundet auf 2 Nachkommastellen

Output: x = 319,94

double x = (Math.round(319.94499999999994 * 1000.0) / 1000.0);
Rundet auf 3 Nachkommastellen

Output: x = 319,945

Würde ich den Output nochmals runden wäre ich bei 319,95

Schule ist schon lange her aber 319.94499999999994 gerundet auf 2 Nachkommastellen ergibt doch 319,95 ... oder?

Meine Frage:

Wir rechne ich in JAVA Kaufmännisch auf 2 Nachkommastellen bei der Zahl 319.94499999999994

folgendes Rechnet leider auch nicht kaufmännisch:

public static double rounding(double value, int places) {
        if (places < 0) throw new IllegalArgumentException();

        BigDecimal bd = BigDecimal.valueOf(value);
        bd = bd.setScale(places, RoundingMode.HALF_UP);
        return bd.doubleValue();
    }

Content-Key: 660629

Url: https://administrator.de/contentid/660629

Printed on: April 26, 2024 at 20:04 o'clock

Member: fisi-pjm
fisi-pjm Mar 09, 2021 at 14:00:50 (UTC)
Goto Top
Hi,

Kaufmännisch runden geht so: Rundung

Wenn du auf die 2. Stelle rundest ist nur deine 3. Stelle relevant. Schau dir den Artikel im Wiki bei Rundungsregeln an.

Aus dem und der Beschreibung von math.round bei Java ergibt sich :

double x = (Math.round(319.94499999999994 * 100.0) / 100.0);

Fertig!

vG
PJM
Member: samet22
samet22 Mar 09, 2021 at 14:51:03 (UTC)
Goto Top
Hallo Fisi-pjm,

danke für deine Antwort ABER

double x = (Math.round(319.94499999999994 * 100.0) / 100.0);

ergibt = 319,94 in Java! Wenn du das in einem Matheheft rechnen würdest dann würde es 319,95 ergeben!

Java rechnet hier 319,944 und rundet dann auf obwohl er eigentlich von hinten weg bis vorne runden müsste. Dies ist halt so beim Kaufmännischen runden. Liege ich hier falsch? so steht es doch oder?
Member: LordGurke
LordGurke Mar 09, 2021 at 21:46:02 (UTC)
Goto Top
Nein, Runden geschieht nicht rekursiv.
Du schaust dir die erste Ziffer von links an, die durch Rundung wegfällt (und nur die) und nur die ist ausschlaggebend.
Du rundest nicht von rechts Ziffer für Ziffer, es ist nur die erste überzählige Nachkommastelle interessant.
Da steht hier eine 4, also wird nicht aufgerundet.
Java rechnet also genau richtig.

Wenn in deinem Matheheft 319,95 rauskommt, ist das falsch face-wink
Member: fisi-pjm
fisi-pjm Mar 10, 2021 at 08:14:13 (UTC)
Goto Top
Zitat von @samet22:
Dies ist halt so beim Kaufmännischen runden.
Nein
Liege ich hier falsch?
Ja
so steht es doch oder?
Nein, siehe bereits oben verlinkten Wiki Artikel.

Gruß
PJM
Member: samet22
samet22 Mar 10, 2021 at 09:37:44 (UTC)
Goto Top
Hi face-smile

okey vielleicht liege ich falsch. Ich dachte, dass Kaufmännisch/Bankwesen runden so wie hier: https://rechneronline.de/runden/ funktioniert.

nun einen kleinen Schritt weiter:

in meiner Datenbank ist der Double Wert 2,5 hinterlegt. Hole ich mir diesen über java so schaut dies folgendes Maßen aus:

double x = resultset.getDouble("Preis");

in der Variable x ist nun die Zahl 2,4999999999999 gespeichert -> Dies ist üblich bei Double werten, kann man auch online nachlesen. UND HIER IST DAS PROBLEM. Runde ich 2,4999999999 so rundet java auf 2. würde ich den tatsächlich richtigen Wert runden (2,5) so würde java auf 3 runden! Wie geht man hier richtig vor?

Dnake!

lg
Member: fisi-pjm
fisi-pjm Mar 10, 2021 at 09:58:50 (UTC)
Goto Top
Moin,

hast du das Problem verstanden? Versuch mal zu ergründen warum das ein bekanntes Problem ist, also warum es genau passiert. (Binärwert und Fließkomma wert, Diskussion hier) mit dieser Erkenntnis und deinem Wissen wie viele Stellen nach dem Komma deine Datenbank den Fließkomma wert speichert, kannst du dein Problem lösen.

Gruß
PJM
Member: WinCobold
WinCobold Mar 10, 2021 at 19:31:39 (UTC)
Goto Top
Hallo samet22,

da kann ich nur raten, eine sinnvolle Programmiersprache zu verwenden (und entweder eine andere Datenbank oder ein anderes Datenformat). Wenn du kaufmännisch rechnen willst, ist Double so gut wie unbrauchbar. Mit Bigdecimal kannst du in Java sicher einiges erreichen, aber ich würde (angelehnt an meinen Namen) so etwas wie Cobol empfehlen.

Gruß vom
WinCobold
Member: fisi-pjm
fisi-pjm Mar 11, 2021 at 15:47:42 (UTC)
Goto Top
Zitat von @WinCobold:

Hallo samet22,

da kann ich nur raten, eine sinnvolle Programmiersprache zu verwenden (und entweder eine andere Datenbank oder ein anderes Datenformat).
Programmiersprachen Bashing hilft dem TO nicht weiter. Auch wenn JAVA nicht das gelbe vom Ei ist was Performance angeht, so ist sie doch eine vollwertige Programmiersprache.

Wenn du kaufmännisch rechnen willst, ist Double so gut wie unbrauchbar. Mit Bigdecimal kannst du in Java sicher einiges erreichen, aber ich würde (angelehnt an meinen Namen) so etwas wie Cobol empfehlen.

Und dann? Dann lernt er wahnsinnig aufwändig eine "neue" (in ganz großen Anführungszeichen) Programmiersprache um dann festzustellen das er bei seinem spezifischen Problem immer noch das falsche Ergebnis raus bekommt. Das ist kein Problem von JAVA. Wen es wirklich interessiert hier der mehr als ausführliche Artikel zum eigentlichen Problem.

Er muss sein Problem Verstehen und in seiner spezifischen Umgebung eine Lösung dafür finden. Hilfestellungen dazu gibt's genug, vorgekaut wird aber nicht.

Gruß vom
WinCobold
Gruß vom
FISI