Präzision bei Typumwandlung zwischen double und String

jueki

Mitglied
Hallo,
in meinem Programm muss ich doublewerte des öfteren als Strings ablegen und später aus dem String wieder einen double machen. Dabei kommt es vor, dass aus einem Wert -z.B 2.5 - nach einigen Umwandlungen 2.49999999999... wird. Gibt es eine Umwandlungsmethode, die auf die letzte doublestelle (also keine fixe Nachkommastellenangabe) rundet oder aber wirklich exakt castet?

Vornehmlich caste ich zur Zeit mit
Java:
Double.valueOf(String)

danke schon mal
jueki
 
Zuletzt bearbeitet von einem Moderator:

RySa

Bekanntes Mitglied
Also an den Umwandlungen liegt es definitiv nicht....:
Java:
	public static void main(String[] args) {
		Double d = 2.5;
		String s = "";
		s = d+"";
		System.out.println(s);
		d = Double.valueOf(s).doubleValue();
		System.out.println(d);
		s = d+"";
		System.out.println(s);

	}

Liefert immer 2.5

Was du meinst ist, dass nach einigen Rechenoperationen wie z.B:
Java:
Double d = 2.5;
d = d + 0.05; //hier wird es noch 2.55 sein
d = d + 0.05; //hier aber schon 2.5999996
Dein Double-Wert plötzlich 2.499999999999999999 ist und nicht 2.5. Das hat aber mit dem Casten nichts zu tun. Doubles sind einfach in dieser Hinsicht ungenau. Du hast 2 Möglichkeiten.

1. Du benutzst BigDecimal
2. Du rundest das Ergebnis bei jeder Rechenoperation auf so viele Nachkommastellen, wie die Zahl hat, die du gerade addierst/subtrahierst. Auf diese Weise solltest du diese x.x999999999999999999 Zahlen vermeiden können.
 
Zuletzt bearbeitet:

jueki

Mitglied
Tatsächlich, RySa hat recht. Das Casten verursacht die Ungenauigkeit nicht sondern die Multiplikation mit einem double-Faktor - tut mir leid.
Das Problem bleibt aber in so weit, dass ich gerne die Werte runden würde und zwar in auf die letzte tatsächliche Nachkommastelle im double. Das Runden selber ist nicht das Problem, aber wie kriege ich die
Anzahl der Nachkommastellen raus?
 

RySa

Bekanntes Mitglied
Auf die Schnelle würd ich sagen (wenn die Performance nicht von sehr großer Bedeutung ist, da diese Lösung etwas unschön ist), kannst du so etwas machen um die Anzahl der Nachkommastellen zu ermitteln:
Java:
double d = 2.75;
int anzahl = (""+g).split("\\.")[1].length();

Und wie willst du denn die "tatsächlichen Nachkommastellen" denn definieren ? Du müsstest vor jeder Rechenoperation, alle zahlen überprüfen, ob sie nicht "ungenau" sind. Oder du rundest das Ergebnis immer auf so viele Nachkommastellen wie der Faktor hat. Das führt aber genauso zu Ungenauigkeiten und ich nehme an, dass dir die Genauigkeit wichtig ist. Von daher - benutz einfach das BigDecimal, da double nicht für präzise Berechnungen gemacht wurde.
 
Zuletzt bearbeitet:

jueki

Mitglied
Also, die Umstellung auf BigDecimal würde mein mittlerweile doch etwas umfangreicheres Projekt ganz schön auf den Kopf stellen. Im Regelfall reichen mir auch genauigkeiten von 10^-9, könnte aber zu Problemen beim Aufmultiplizieren führen.
Ich habe zwischenzeitlich natürlich auch noch experimentiert und bin zu folgender Lösung gekommen:

Java:
	double val = 2.5;
System.out.println(""+val);

System.out.println("");
System.out.println("multiplikation mit 1/1000000 :");
val = val * 1.0e-6 ;
System.out.println(""+val);

System.out.println("");
System.out.println("Runden der 16. Dezimalstelle :");

// hier ist der wichtige Schritt: ...
val = Math.round(val*Math.pow(10, 16))/Math.pow(10, 16);

System.out.println(""+val);

Klappt soweit im Beispiel. Aber hat ein double immer maximal 16 Stellen oder ist das auf 64Bit-Rechnern anders. Mein Problem ist jetzt also nur noch wie ich die "16" sauber ermitteln kann.

(klappt übrigens nicht mit :
Java:
val = Math.round(val*Math.pow(10, 16)) * Math.pow(10, -16);
nur so zur Info.)

jueki
 

RySa

Bekanntes Mitglied
Java:
val = Math.round(val*Math.pow(10, 16)) * Math.pow(10, -16);

Dass es damit nicht klapp, liegt wahrscheinlich daran, dass der Wert so klein ist, dass double schon sagt "hmm ok, machen wa ne 0 draus". Bin da aber nicht sicher.

Und dass mit den 16 Stellen, verstehe ich bei double auch nicht ganz. Habe jetzt mal paar Tests auf einem 32-bit Rechner durchgeführt, und manchmal nimmt der 17 Stellen an, manchmal 16, aber immer mindestens 16. Ich wüsste jetzt aber nicht was das mit dem Problem zu tun hat, dass er manchmal statt 0.5 zu addieren, 0.49999996 addiert. Wenn du das Ergebnis auf 16. Stelle rundest, hast du immer noch diese ungenauigkeit, dass du mit 0.49999996 gerechnet hast und nicht 0.5 ... Die Umstellung auf BidDecimal mag vielleicht "nerfig" sein, ist abber immer noch besser, als vor jeder Rechnung die Zahlen zu runden und sonst noch was. Ist aber deine Entscheidung.
 

jueki

Mitglied
Ich wüsste jetzt aber nicht was das mit dem Problem zu tun hat, dass er manchmal statt 0.5 zu addieren, 0.49999996 addiert
... das ist wohl ein Missverständnis: Mein Problem war, dass ich bei einer Multiplikation kein exaktes ergebnis bekam weil der Faktor als double-Wert nicht exakt darstellbar ist. Ich weiß nicht welchen Umfang diese Ungenauigkeit annehmen kann, aber in meinen Test reichte immer ein Runden der 16. Dezimalstelle aus. Erstaunlicherweise tritt zB. bei einer Multiplikation 1.0/3.0*10e-6 oder 2.0/3.0*10e-6
keine Ungenauigkeit zu tage (hätte ich hier aber erwartret).
Aufgetreten ist das Problem bei einer if-Abfrage: Der User gibt 2.5 ein und das System vergleicht mit 2.49999.... was daraus resultiert, dass eine Einheitenkorrektur durchgeführt werden muss. Es geht also nicht um die letzte signifikante Stelle im double.

jueki
 

jueki

Mitglied
guten morgen zusammen,

ich möchte mich mit java befassen, komm da aber nicht weiter. kann mir jemand helfen
lg jessy

... ich fürchte, in diesem Diskussionsfaden bist Du jetzt eher irrtümlich. Vielleicht machst Du besser einen eigenen auf? ... und vielleicht stellst Du die Frage auch etwas präziser, denn so kann man alles oder nichts dazu sagen. Wenn Du noch ganz grün bist, frag doch mal das Web nach Anfänger Tutorials für Java.

jueki
 

RySa

Bekanntes Mitglied
Wenn es dann daran hackt, dass eine Usereingabe vergleicht werden soll, und es aber unglücklicherweise z.B 2.5 mit 2.49999 vergleicht, dann Prüfe vorm Vergleich, wie viele Nachkommastellen die Zahl hat, die der User eingegeben hat, runde deine Zahl auf die Anzahl der Nachkommastellen (zumindest für diesen Vergleich, das Original kannst du behalten) und Vergleiche sie dann erst (nach dem Motto - wenn ich etwas in Metern messe, dann kann es nicht auf den Centimeter genau sein).

Oder aber du Vergleichs die nicht mit == sondern setzst dir eine bestimmte Fehlertoleranz von z.B 0.0004 und überprüfst dann ob es stimmt . zB
Java:
if (zahl >= eingabe-0.0004 && zahl <= eingabe+0.0004){
//Inhalt
}

Und nochmal zu dem Runden auf die 16. Stelle. Was macht das denn für ein Unterschied, wenn double sowieso automatisch auf die 16. bzw 17. Stelle gerundet wird (also z.B aus 678.555555555555555 wird 678.5555555555556 bzw. 678.55555555555556 - zumindest was die Umwandlung in Strings angeht).
 

jueki

Mitglied
ja, da hast Du recht, wenn nicht ein langer Schwanz ...99999 oder ...000001 als Dezimalstellen im double steckten, bringt das Runden nichts. Meine Beobachtung bisher war aber immer der lange Schwanz mit ...99999. Glücklicherweise konnte ich auch eine Stelle in meinem Projekt ausmachen, an der die Ungenauigkeit entsteht, und zwar genau in der Funktion, die die Einheiten zwischen angezeigter und interner Einheit (intern ist immer Meter) umrechnet. Seit ich in dieser Funktion die oben beschriebene Rundung auf die letzte Stelle eingeführt habe, läuft alles prima.
Die Idee, die Genauigkeit der vom User vorgegebenen Zahl als Maßstab zu nehmen ist aber auch prima, Du hast ja schon oben beschrieben, wie man die raus kriegt.
Mit einer fest vorgegebenen Toleranz zu vergleichen habe ich so ein bisschen Bauchweh, kann ich nicht überblicken, ob ich dann nicht den Teufel mit dem Belzebub austreibe, eben genau so wie jetzt, wenn ich immer fest 16 Stellen im double annehme.

OK, aber ich glaube das führt jetzt von der anfänglichen Fragestellung zu weit weg. Vielen Dank an alle, die sich mit dem Thema befaßt haben und besonders an RySa. Eine Funktionale Lösung habe ich jetzt ja erst mal und eine Menge Ideen dazu.

Wenn aber jemand doch noch weiß, wie ich die Anzahl der möglichen Dezimalstellen im double raus kriege währe ich ganz froh.

jueki
 

jueki

Mitglied
... ach ja, und noch eins oben drauf: habe es zu Anfang nicht bemerkt, aber durch die Multiplikation mit 10^16 stößt man schnell an die maximalgrenze der Doubles. Man muss also doch auf BigDecimal zurückgreifen. Meine Rundungsfunktion sieht jetz also so aus:
Java:
	public static double precision(double val)
	{
		int n = 16;
		BigDecimal bigdec = BigDecimal.valueOf(val);
		return (bigdec.setScale(n, BigDecimal.ROUND_HALF_UP)).doubleValue();
	}

Das scheint's jetzt zu tun.
jueki
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Runden mit Präzision vs. Runden mit Nachkommastellen Java Basics - Anfänger-Themen 4
C Typumwandlung von int<-->double Java Basics - Anfänger-Themen 6
C Implizite Typumwandlung nach Java 8 anders? Java Basics - Anfänger-Themen 7
J Frage zur expliziten Typumwandlung Java Basics - Anfänger-Themen 5
J Casten (Typumwandlung) Java Basics - Anfänger-Themen 12
H Typumwandlung String --> Int (ganz einfach) Java Basics - Anfänger-Themen 9
B Typumwandlung Java Basics - Anfänger-Themen 2
P Typumwandlung Object in double Java Basics - Anfänger-Themen 12
S Typumwandlung String zu double? Java Basics - Anfänger-Themen 6
V Auf Typumwandlung prüfen Java Basics - Anfänger-Themen 8
B Typumwandlung von int nach String Java Basics - Anfänger-Themen 8
C Kommunikation zwischen 2 Klassen Java Basics - Anfänger-Themen 9
Distanz zwischen zwei Zeichenfolgen in einem String bestimmen Java Basics - Anfänger-Themen 5
S Unterschied zwischen Denkweisen Java Basics - Anfänger-Themen 13
O Klassen Zusammenspiel zwischen 2 Klassen Java Basics - Anfänger-Themen 1
Ras Unterschied zwischen parser xml and api xml Java Basics - Anfänger-Themen 7
X Was ist der Unterschied zwischen materialisierten und nichtmaterialisierten Attributen einer Klasse? Java Basics - Anfänger-Themen 1
F Abstand zwischen zwei Objekten berechnen wie? Java Basics - Anfänger-Themen 1
S Längster Pfad zwischen zwei Vertices in einem Graph Java Basics - Anfänger-Themen 3
U Erste Schritte nextGaussian zwischen zwei Werten Java Basics - Anfänger-Themen 19
jhCDtGVjcZGcfzug Was ist der Unterschied zwischen diesen Quellcodes? Java Basics - Anfänger-Themen 3
rafi072001 Assoziation zwischen Musiker und Label Java Basics - Anfänger-Themen 1
I Best Practice Saubere Verbindung zwischen API und Business Layer mit DTO's Java Basics - Anfänger-Themen 2
A Parametar übergabe zwischen Methoden Java Basics - Anfänger-Themen 26
W User zwischen Optionen wählen lassen Java Basics - Anfänger-Themen 1
I Differenz zwischen LocalDateTime Java Basics - Anfänger-Themen 4
Leo_1789 Differenz ausrechnen zwischen denn idealgewicht und denn echten Gewicht Java Basics - Anfänger-Themen 7
E Wie gebe ich alle Daten zwischen zwei Zeitpunkten aus? Java Basics - Anfänger-Themen 2
P Methode die ausgibt wie viele Primzahlen es zwischen 2 und n gibt Java Basics - Anfänger-Themen 10
C Kommunikation zwischen 2 Klassen Java Basics - Anfänger-Themen 3
marcooooo Separator zwischen allen Zeichen eines Strings einfügen Java Basics - Anfänger-Themen 29
NeoLexx Zuweisungskompatibilität zwischen Vererbungsbeziehungen (Polymorphie) Java Basics - Anfänger-Themen 18
L Threads Synchronisierung zwischen threads Java Basics - Anfänger-Themen 4
N Berührung zwischen Rechtecken Java Basics - Anfänger-Themen 5
Y Unterschied zwischen WindowBuilder und herkömmlichen erstellen des GUI´s? Java Basics - Anfänger-Themen 9
J Wert zwischen JFrames übergeben Java Basics - Anfänger-Themen 2
U Worin besteht der Unterschied zwischen call by reference und call by value? Java Basics - Anfänger-Themen 14
E Unterschied zwischen new und import Java Basics - Anfänger-Themen 5
J Punkt auf,über,unter oder zwischen 2 Geraden Java Basics - Anfänger-Themen 14
A Kommunikation zwischen nebenläufigen Threads Java Basics - Anfänger-Themen 4
B Unterschied zwischen (List<T> a) und (T[] a) Java Basics - Anfänger-Themen 7
Dilara_K Abstand zwischen den Doppelwerten in einem Array herausfinden Java Basics - Anfänger-Themen 20
S Nach dem Herüberschieben eines Arrays zwischen 2 Frames öffnet sich das Frame nicht mehr Java Basics - Anfänger-Themen 12
D Zufallszahl zwischen 10 und 99? Java Basics - Anfänger-Themen 5
J Objektzugriff zwischen disjunkten Klassen Java Basics - Anfänger-Themen 1
L Den Winkel zwischen zwei Vektoren berechnen! Java Basics - Anfänger-Themen 2
A Methoden Unterscheid zwischen public und ohne Java Basics - Anfänger-Themen 9
X Input/Output Höchste Temperaturschwankung zwischen 2 Tagen Java Basics - Anfänger-Themen 2
Bluedaishi der Monat zwischen zwei Datumsangaben Java Basics - Anfänger-Themen 15
R Threads Pause zwischen zwei Schleifen Java Basics - Anfänger-Themen 1
Aprendiendo Unterschied zwischen Referenzvariable und Instanzvariable. Java Basics - Anfänger-Themen 2
N Unterschied zwischen Checked und Unchecked Exceptions Java Basics - Anfänger-Themen 12
S Parameterübergabe zwischen zwei Programme Java Basics - Anfänger-Themen 4
S Erste Schritte Zwischen zwei Punkten ein Minimumpkt./Maxima finden Java Basics - Anfänger-Themen 1
K Klassen Array zwischen Klassen übergeben Java Basics - Anfänger-Themen 2
Arif OOP Die Bindung zwischen einem äußeren und einem inneren Objekt Java Basics - Anfänger-Themen 2
schoenosrockos Unterschied zwischen Objekten und vererbungen Java Basics - Anfänger-Themen 1
S OOP Variablen zwischen mehreren Klassen Java Basics - Anfänger-Themen 11
H Klassen Konstruktor Parameter als Instanzvariablen zwischen speichern... Java Basics - Anfänger-Themen 11
F Klassen Kommunikation zwischen Klassen Java Basics - Anfänger-Themen 4
J Variablen Unterschied zwischen lokalen-, Instanz-, Klassenvariablen Java Basics - Anfänger-Themen 6
N Dauer zwischen zwei LocalDateTime Objekten berechnen? Java Basics - Anfänger-Themen 4
P Ungerade Zahlen ausgeben lassen zwischen Spannweite zweier eingegeben zahlen Java Basics - Anfänger-Themen 6
V Zufallswert zwischen zwei Zahlen a und b Java Basics - Anfänger-Themen 12
H Datentypen Tage zwischen zwei Datums berechnen Java Basics - Anfänger-Themen 4
M Variable zwischen Klassen übergeben Java Basics - Anfänger-Themen 5
A attach source: Zusammenhang zwischen JAR und .class/.java Dateien? Java Basics - Anfänger-Themen 2
L Unterschied zwischen Klassen - und Instanzvarbiablen Java Basics - Anfänger-Themen 1
F Vererbung von Attributen zwischen zwei Klassen Java Basics - Anfänger-Themen 6
F Referenzen zwischen Methoden Java Basics - Anfänger-Themen 5
B Distanz zwischen zwei Punkten Java Basics - Anfänger-Themen 4
D Suche nach der Anzahl von Zonen zwischen zwei Punkten Java Basics - Anfänger-Themen 2
G Zugriff zwischen Klassen Java Basics - Anfänger-Themen 15
S Funktion die mir fuer einen String eine Zahl zwischen 0.0 und 1.0 zurueckliefert..? Java Basics - Anfänger-Themen 9
S Unterschiede zwischen equals und contains Java Basics - Anfänger-Themen 2
S Leerzeichen zwischen zwei Zeichen im String entfernen Java Basics - Anfänger-Themen 19
N Werte zwischen Klassen austauschen Java Basics - Anfänger-Themen 1
M Unterschied zwischen Classpath eines Eclipse Projektes und dem CLASSPATH? Java Basics - Anfänger-Themen 3
Thallius Best Practice Events zwischen eigenen Klassen Java Basics - Anfänger-Themen 2
A if-Anweisung zwischen zwei Punkten Java Basics - Anfänger-Themen 1
S Erste Schritte TAB-Wechsel zwischen TextFields Java Basics - Anfänger-Themen 1
B Relativer Pfad zwischen zwei Files Java Basics - Anfänger-Themen 2
M Drag & Drop - Interaktion zwischen Java und dem OS Java Basics - Anfänger-Themen 1
S Erste Schritte Tage zwischen 2 Daten berechnen Java Basics - Anfänger-Themen 6
Z Differenz zwischen 2 Daten berechnen, ohne importiere Funktionen! Java Basics - Anfänger-Themen 10
A Datum zwischen zwei Daten berechnen und in Tagen anzeigen Java Basics - Anfänger-Themen 4
D Unterschied zwischen double und Double Java Basics - Anfänger-Themen 4
Q Unterschied zwischen static und keinem Modifier Java Basics - Anfänger-Themen 15
K Unterschied zwischen Jar, war und ear Dateien Java Basics - Anfänger-Themen 3
S Problem bei Kollision zwischen Array-objekten! Java Basics - Anfänger-Themen 2
M Länge der Strecke zwischen zwei Punkten Java Basics - Anfänger-Themen 10
T Unterschied zwischen Integrationstest und JUnit test? Java Basics - Anfänger-Themen 12
T zwischen den Strings soll ein plus(+) stehen Java Basics - Anfänger-Themen 5
S Methoden Tage zwischen 2 Daten Java Basics - Anfänger-Themen 19
M Typcasting zwischen ganzen Zahlen Java Basics - Anfänger-Themen 7
K Unterschied zwischen break und continue in einer Schleife Java Basics - Anfänger-Themen 14
A Exakte Unterschied zwischen Java EE und Java SE? Java Basics - Anfänger-Themen 4
J Unterschied zwischen statische und nicht statische Methoden? Java Basics - Anfänger-Themen 14
N Winckel zwischen zwei Punkten Java Basics - Anfänger-Themen 9
O Java unterschied zwischen Interface und Interface_Referenzen!!?? Java Basics - Anfänger-Themen 7

Ähnliche Java Themen

Neue Themen


Oben