Best practice: Multiplizieren zweier Zahlen
-
Hallo,
sagen wir ich möchte eine elementare mathematische Funktion in Java nutzen, mit 5 Nachkommastellen Genauigkeit. x*y normalerweise. Hat sich so eingebürgert, ist kurz und verständlich und kennt man in jeder Sprache.
In Java muss ich so etwas machen, damit ich ohne Verlust der Präzision Doubles multiplizieren kann:BigDecimal b = new BigDecimal(value*10000.0); double result = b.setScale(5, RoundingMode.HALF_UP).doubleValue();
Ist das der empfohlene Weg? Kommt mir etwas bloated vor...
-
Hi.
Ich verstehe nicht, was Du meinst. Warum multiplizierst Du nicht gleich 2 doubles miteinander? Was soll da denn an Präzision verloren gehen. ...vor allem, wenn Du eh nur 5 Stellen brauchst?
-
Hallo,
es geht um folgenden Code:
// Funzt mit BigDecimal assertEquals(1.0, PipUtils.getPips(0.0001)); // Bei reiner Doublemultiplikation assertEquals(1.0, PipUtils.getPips(0.0001)); # Fehler: Expected "1.0" - Got "0.99999999998" public class PipUtils { public static double getPips(double value) { BigDecimal b = new BigDecimal(value*10000.0); return b.setScale(5, RoundingMode.HALF_UP).doubleValue(); } // vs public static double getPips(double value) { return value*10000.0; }
Ergibt das Sinn für dich?
-
Bestimmte Zahlen können halt nicht als double dargestellt werden. Hat nichts mit Java zu tun, sondern mehr mit der Binärdarstellung im Allgemeinen. Aus diesem Grund ist double zum Beispiel auch nicht geeignet, wenn es um Geldbeträge oder so geht. Um Dinge, von denen es keine "Bruchteile" gibt.
Worum geht es denn jetzt genau? Um den Rechenvorgang? Dann ist double genauer, als wenn Du irgendwo einfach nach 5 Stellen rundest. Um die Ausgabe? Da kannst Du das Runden auf 5 Stellen auch anders hinkriegen. Vermutlich würde Dir da schon die Klasse "DecimalFormat" weiterhelfen.
-
Da wird halt noch gerundet, oder?
-
Jein!
Es wird ein String erzeugt, der aussieht, als würde ein
double gerundet worden sein.
-
Hallo,
das prinzipielle Problem mit den Doubles und der Nichtdarstellbarkeit von einigen Zahlen ist mir bekannt. Ich habe aber eigentlich erwartet, dass die Java VM sich um dieses Detail kümmert... Die DecimalFormat Klasse habe ich gesehen - dort werden in einigen Artikeln im Ernst Strings eingegeben um zu rechnen. Wtf???
Ich wollte nur wissen, ob mein bloated Weg OK ist?
-
Headhunter schrieb:
das prinzipielle Problem mit den Doubles und der Nichtdarstellbarkeit von einigen Zahlen ist mir bekannt. Ich habe aber eigentlich erwartet, dass die Java VM sich um dieses Detail kümmert...
Das ist doch ein Problem mit dem Binärsystem. Dass das die VM weg machen würde, wäre mir neu und wohl auch sehr aufwendig.
Die DecimalFormat Klasse habe ich gesehen - dort werden in einigen Artikeln im Ernst Strings eingegeben um zu rechnen. Wtf???
Ich wollte nur wissen, ob mein bloated Weg OK ist?Naja, wenn man sich das so überlegt, dann muss man entweder mit mehreren Integern oder mit nem String rechnen (wie wir Menschen ja auch). Wenn man nur mit float oder double rechnet, wird man nie die Genauigkeit haben.
Wenn du es genau brauchst (z.B. für Finanzen), dann würde ich nicht mit double rechnen.
-
Hat denn einer ein Beispiel, wie man zuverlässig mit Finanzwerten arbeitet? Ich find das sehr nervig...
-
Headhunter schrieb:
Hat denn einer ein Beispiel, wie man zuverlässig mit Finanzwerten arbeitet?
Eine Möglichkeit wäre, mit Ganzzahlen zu rechnen. ...also mit long. ...wenn Du es "richtig" machen willst, wirst Du aber nicht daran vorbeikommen, einen eigenen Datentyp dafür zu erstellen, der vielleicht intern long nutzt, aber nach außen hin halt alle möglichen Methoden anbietet, die so ein Datentyp halt haben sollte. Dieser Datentyp würde dann vermutlich auch ein Feld enthalten, das die Währung beschreibt.
-
Headhunter schrieb:
Hat denn einer ein Beispiel, wie man zuverlässig mit Finanzwerten arbeitet?
Dazu gibt es die beiden Klassen BigDecimal bzw. BigInteger.
MfG,
Hilefoks
-
Hilefoks schrieb:
Headhunter schrieb:
Hat denn einer ein Beispiel, wie man zuverlässig mit Finanzwerten arbeitet?
Dazu gibt es die beiden Klassen BigDecimal bzw. BigInteger.
Hi.
Die sind dazu eben nicht da.
-
Sondern?
-
Mr. N schrieb:
Sondern?
Lesefaul? Gregor hat doch schon seinen Vorschlag gepostet.
MfG SideWinder
-
-
Danke für den Link, hilft mir weiter!
Was ist bei Java echt am meisten vermisse ist die .NET Standardbibliothek und die C# Sprachfeatures. Aber man kann ja nicht immer alles haben...
-
SideWinder schrieb:
Mr. N schrieb:
Sondern?
Lesefaul? Gregor hat doch schon seinen Vorschlag gepostet.
Ich hätte die Frage so verstanden, dass er wissen will, für was die dann sind und wieso nicht dafür.
-
Was spricht eigentlich gegen (Edit: Naja, ist eigentlich eh Gregors Vorschlag...):
class MoneyAmount { /** Currency */ private final Currency currency; /** Amount of money multiplied by 100 */ private final long amount; ... public long getAmount() { return amount; } public long getCents() { return amount % 100; } public long getGibtsDafürÜberhauptEinWort() { return amout - getCents(); } }
MfG SideWinder
-
@hmm??: Ich hab die bisher nur bei der Implementierung von verschiedenen kryptografischen Algorithmen in der Schule benutzt. Die Schnittstelle deutet darauf hin, dass sie darauf auch ausgelegt sind.
MfG SideWinder
-
Faktor 100 ist wenig international. Das sollte man flexibler lösen.