double (un-)genauigkeit

javalerner86

Mitglied
Hallo zusammen,

das problem der ungenauigkeit bei der berechnung von gleitkommazahlen ist vielen bestimmt bekannt (Ursache: aus umrechnung der sprachen in bits usw.).

Gibt es eigentlich eine Möglichkeit dieses "Problem" zu umgehen oder zu beheben?

ich rede nicht von geldbeträgen zusammenrechnen, wo man einfach sagen kann: multiplizier mal hundert und nimm dafür den typ integer. Ich rede z.B. von Messwerten, die unterschiedlich viele Ziffern hinter dem komma haben können.
Wäre schade, wenn ein Messergebnis z.B. um paar Millimeter von der Literatur abweicht und das sonst so schöne Ergebnis "versauen" würde. Vielen Dank.
 

javalerner86

Mitglied
Danke, ok, dass hatte ich auch gefunden. Aber kann man aus dieser dann eine Wurzel ziehen? dies habe ich nicht gefunden=(

Math.sqrt(Decimal Zahl);

sqrt funktioniert leider nur mit double oder float Zahlen, oder?
 

Marco13

Top Contributor
Beschreib' vielleicht nochmal genauer, worum es geht. So pauschal kann man da kaum mehr sagen als "BigDecimal", aber das ist schon "schweres Geschütz" (eine kompliziertere Rechnung darauf umzustellen ist ein Krampf, und birgt auch einiges an Bug-Potential....).
 

AquaBall

Top Contributor
das problem der ungenauigkeit bei der berechnung von gleitkommazahlen ist vielen bestimmt bekannt
Gibt es eigentlich eine Möglichkeit dieses "Problem" zu umgehen oder zu beheben?

Ganz losgelöst von Computer:
Das Problem kannst du auch im echten Leben nie lösen!
Diese "Ungenauigkeit" begleitet dich auf jedem Zettel und überall in der Methemetik.

Schon "primitive" Zahlen wie 1/3 kannst du NIE im Leben exakt schreiben.
1/3 = 0.333 333 333 333 333 ... Irgendwann ist der Zettel zu Ende. Irgendwann musst du den Rest als Ungenauigkeit akzeptieren.
Bei "schwierigren" Zahlen wie Wurzel(2) = 1,41421356... ist noch viel früher Schluss.

Die Mathematik behält sich ihre Genauigkeit nur dadurch, dass sie symbolische Schreibweisen erfunden hat (Peridodenpunkt), oder überhaupt symbolisch bleibt (Pi, Wurzel, e ...).
und das auch nur, solange es "Mathematik" bleibt, und kein "Rechnen" wird.

Es ist aber eine Irrmeinung, dass der Computer deshalb ungenauer rechnen muss als der Mensch.
Tatsache ist, dass der Computer im Binärsystem nur Brüche von 2 exakt darstellen kann,
Und das dem Menschen im Dezimal System nur mit den Faktoren 2 und 5 gelingt.
Jede andere Zahl MUSS ungenau bleiben.

Deshalb wurden auch genügend Systeme entwickelt, in denen du am Computer symbolisch EXAKT rechnen kannst.
 
K

kaschik

Gast
@AquaBall: Dass man numerisch nicht exakt rechnen kann, sollte jedem klar sein und wird hier auch von niemandem verlangt! Der TO spricht ausdrücklich von Messwerten und die können selbst schon nicht exakt sein. Aber wenn ein Messwert mit einer bestimmten Genauigkeit vorliegt, dann sollte diese Genauigkeit auch beibehalten werden.

@javalerner86: Wenn du die Wurzel ziehen willst, dann geht das mit Math.sqrt nicht mehr, aber dir stehen genug Alternativen offen:
- du schreibst dir selbst eine sqrt-Methode, die mit BigDecimal arbeitet. Algorithmen siehe Wikipedia: Methods of computing square roots - Wikipedia, the free encyclopedia
- du nutzt Libraries, die solche Methoden bereitstellen. Zum Beispiel JScience bietet eine Decimal-Klasse an, mit der man auf eine bestimmte Genauigkeit Wurzeln ziehen kann: JScience
 

javalerner86

Mitglied
@ alle vier Beiträge erstmal vielen Dank für die Hilfe, obwohl das "Problem" nicht so richtig gelöst ist, sorry

Ich möchte gemessene Werte mit einem Programm mit Formel berechnen (welche formel ist ja eigentlich egal, begründung jetzt). Ein einfaches Beispiel: 1.0-0.8 ergibt eigentlich 2.0, aber das Programm gibt auf Grund der Umrechnung der Zahlen in ein Binärsystem nicht die richtig exakte Zahl aus, sondern 1.99999999996 oder so.
Ich bin mir darüber im klaren, dass nicht unendlich viele Ziffen hinter dem Komma angezeigt werden können, aber das eben gezeigte Beispiel ist erschreckend (@Aquaball). Für soetwas suche ich eine Lösung. Diese könnte ich dann allgemein übertragen.

@kaschik: danke, ich werde mir die Klasse JScience ansehen
 

HoaX

Top Contributor
Stell dir die Frage ob es für den Benutzer relevant ist ob das Ergebnis 2.00000001 oder 2.0000 ist --> Zeig nur eine bestimmte Anzahl von Nachkommastellen an, dann wird aus der 1.999999999999 auch wieder eine 2.0000

Java:
System.out.printf("%.4f", 1.9999999999999999999d);
 

javalerner86

Mitglied
@Hoax
Naja wenn das ergebnis nicht für weitere berechnungen verwendet werden würde, dann stimme ich dir zu. nur müsste ich mit einer matrix berechnung (und so weiter) die exakte Zahl haben. und genau die das Problem habe ich nun. Wenn ein Eintrag genau 0 werden soll, aber trotzdem irgendwas kleines herauskommt, stimmt die weitere berechnung nicht mehr.
Falls es was bringt: ich hab versucht einen Algorithmus zur Berechnung von Gleichungssystemen zu programmieren. Klappt auch prima, jedoch ist es schade, wenn schon bei einfachen Zahlen der Unterschied zu exakten ergebnissen erheblich ist, als wenn man von hand rechnet. Dann brauch ich mir keine gedanken zu machen, wenn ich statt einfachen zahlen dann messwerte als zahlen einlesen lasse. Das ist die eigentliche idee dahinter.
Vllt gibt es doch eine lösung dazu.
 

Marco13

Top Contributor
Lass' dich von sowas wie 1.0/9.0=0.111111111111111111113243 erstmal nicht zu sehr irritieren.

Bei "komplexeren" numerischen Problemen, oder etwa einem Gleichungssystemlöser, muss man IMHO zwei vollkommen unterschiedliche Fälle betrachten:

Erstens, dass die Zahlen (schon in einfachen Fällen) nicht "schön aussehen": Wenn man den Benutzer eine 2x2-Matrix eingeben läßt und mit einem Vektor multipliziert, und dann die Ausgabe mit Standard-Formatierung eben 1.0000000000000001231 ist, kann man (wenn es wirklich nur darum geht) die Formatierung ändern, damit 1.0 angezeigt wird.

Der zweite Fall ist, dass die Ungenauigkeit sich wirklich fortpflanzt und auf-akkumuliert, und am Ende ein numerisch vollkommen falsches Ergebnis rauskommt. Das ist dann aber ein Problem, das in der Praxis auch nicht mit BigDecimal gelöst werden kann. (Einen Gleichungssystemlöser für 1000x1000-Matrizen auf BigDecimal umstellen würde keinen Spaß machen, und über die Ausführungzeit im Vergleich zu double bräuchten wir dann gar nicht zu reden). In solchen Fällen muss man vermutlich tiefer ansetzen: Andere (numerisch stabilere) Lösungsverfahren suchen, bessere Preconditioner verwenden oder was auch immer...
 

javalerner86

Mitglied
@Marco13:
Danke für deinen Beitrag. Genau dein zweiter Fall trifft trifft auf mein Problem zu. Ich benutze vier oder fünf matrixmultiplikationen und der fehler pflanzt sich so fort, dass sich mein ergebnis von 2.6 auf 0.2 ändert, was ein fataler fehler ist (ein Fehler aber 4 oder 5 stelle hinter dem komma, könnte ich --auch wenn das schon ein wenig ärgerlich ist-- verschmerzen). Daher hatte ich gehofft, ich hätte wirklich im i-net eine einfache lösung dafür übersehen (auch wenn ich hier vllt getadelt worden wäre, dass ich nicht weitergesucht hätte:D).
Wenn jemand eine tolle lösung hat, die das Problem löst, BITTE posten. Nach der Suche bei google musste ich feststellen, dass ich nicht der einzige mit dem problem bin.
 
K

kaschik

Gast
Solange du im Bereich der rationalen Zahlen bleibst, also keine Wurzeln ziehst o. Ä., kannst du dir doch auch eine Bruch-Klasse schreiben. Für die Multiplikation von Matrixen und z. B. Grauß-Jordan eignet sich das hervorragend.
 

Kevin94

Top Contributor
Ich weis zwar nicht ob das was hilft, weil ich's selber noch nie gebraucht habe, aber in Java gibts doch auch den
Code:
strictfp
Zusatz für Methoden, wenn diese absolut sauber mit Gleitkommazahlen rechnen sollen. Zusätzlich zu Math gibts auch die Klasse StrictMath, die sich von Math nur darin unterscheidet, dass alle Methoden diesen Zusatz tragen.
Wenn das das Problem nicht lösen sollte, halte ich es auch für eine gute Idee wenn du dir eine Bruchklasse schreibst und dann mit Ganzzahlen rechnest und am Ende kürzt.
 
P

protip

Gast
Ich weis zwar nicht ob das was hilft, weil ich's selber noch nie gebraucht habe, aber in Java gibts doch auch den
Code:
strictfp
Zusatz für Methoden, wenn diese absolut sauber mit Gleitkommazahlen rechnen sollen.
Toller tipp, dadurch werden die Rechnungen doch höchstens noch ungenauer... :rolleyes:
 

Kevin94

Top Contributor
Einen Versuch ist es trotzdem Wert, bevor man Stunden darin investiert ein fast fertiges Programm komplett umzustellen (Meine Meinung).
 
R

reNur

Gast
Du musst halt einfach vorher den maximalen Rundungsfehler deines Algorithmus ausrechnen, und dann die Genaugikeit so lange erhöhen, bis der Rundungsfehler sozusagen im Toleranzbereich ist.
 

HoaX

Top Contributor
Einen Versuch ist es trotzdem Wert, bevor man Stunden darin investiert ein fast fertiges Programm komplett umzustellen (Meine Meinung).

Ist es nicht! Wenn man sich durchliest was strictfp mach, dann ist es auch klar warum. Warum sollte es einen versuch Wert sein u.U. noch ungenauer zu rechenen und zu hoffen genauere Ergebnisse zu bekommen?
 

mla.rue

Bekanntes Mitglied
kA wie groß jetzt deine Messwerte sind (ich hatt ein ähnliches Problem mit Kundenabrechnung, das hatte halt 2 Nachkommastellen). Multipliziere deinen Messwert mit 100 (oder mehr/weniger) und konvertiere es so in einen int, dann addieren, und dann wieder durch 100 teilen
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Datentypen Genauigkeit Double Java Basics - Anfänger-Themen 8
K Mal wieder: double-Genauigkeit Java Basics - Anfänger-Themen 14
W Double or Float zusammenrechnen Java Basics - Anfänger-Themen 15
I Review von euch erwünscht, double Rechnung falsch Java Basics - Anfänger-Themen 34
X wie bekomme ich durch Eingabeaufforderung definierte double in einen Befehl, welcher 3 erwartete double braucht? Java Basics - Anfänger-Themen 3
Avalon String in Double bzw. Währung konvertieren Java Basics - Anfänger-Themen 6
MoxMorris Integer.MAX_VALUE und Double.MAX_VALUE Unterschied Java Basics - Anfänger-Themen 3
krgewb Double mit zwei Nachkommastellen Java Basics - Anfänger-Themen 2
B Produkt eines double - streams Java Basics - Anfänger-Themen 3
Lion.King Fehler in double und int Java Basics - Anfänger-Themen 7
F java: incompatible types: possible lossy conversion from double to int Java Basics - Anfänger-Themen 1
J Double Variable und Addition Java Basics - Anfänger-Themen 2
F Double Ausgabe nicht wissenschaftlich Java Basics - Anfänger-Themen 16
S Fragen zu Ausgabe double und float Java Basics - Anfänger-Themen 3
Kotelettklopfer Variablen Double zwingen Ganzzahlen mit 2 Nachkommastellen auszugeben Java Basics - Anfänger-Themen 10
A possible lossy conversion from double to int Java Basics - Anfänger-Themen 5
I Output BigDecimal anstatt double / Problem beim Rechnen Java Basics - Anfänger-Themen 16
L ArrayList<String> --> double[] array Java Basics - Anfänger-Themen 18
FelixN Array mit verschiedene Datentypen als Rückgabewert? (Long und Double) Java Basics - Anfänger-Themen 3
J Transformation zweier Integer in ein Double Java Basics - Anfänger-Themen 26
N The method setSaldo(double) in the type Konto is not applicable for the arguments (int, int) Java Basics - Anfänger-Themen 2
C Konvertierung des int typs in den double typ für die Ausgabe mit Nachkommastellen Java Basics - Anfänger-Themen 4
V Erste Schritte Die Nuller bei double NICHT abschneiden Java Basics - Anfänger-Themen 4
Y Datentypen Double Division ungenau Java Basics - Anfänger-Themen 45
L Datentypen Rechnen und abrunden mit double Java Basics - Anfänger-Themen 7
M Writer für unterschiedliche Obj/inbt/double erstellen? Java Basics - Anfänger-Themen 1
F Character umwandeln als Double Werte Java Basics - Anfänger-Themen 8
M Double Wert nach n abschneiden ohne zu runden Java Basics - Anfänger-Themen 1
D Methode mit Übergabe double und Rückgabe String Java Basics - Anfänger-Themen 2
P Hilfe bei Double Java Basics - Anfänger-Themen 1
B Rückgabe von zwei Werten: String und double Java Basics - Anfänger-Themen 14
B HQL / Hibernate, GroupBy und Ausgabe als Double Java Basics - Anfänger-Themen 1
M Konvertierung String -> double Java Basics - Anfänger-Themen 8
A Double Scan eingrenzen Java Basics - Anfänger-Themen 2
O Erste Schritte Potenzmethode per double Java Basics - Anfänger-Themen 11
A Random Double mit Math.round() runden? Java Basics - Anfänger-Themen 1
H Double oder nicht? Java Basics - Anfänger-Themen 7
J int array als double array ausgeben Java Basics - Anfänger-Themen 9
M Int und Double in Array speichern Java Basics - Anfänger-Themen 1
J String, Int und double Array sortieren Java Basics - Anfänger-Themen 16
B Hashing (verkettet/double) Java Basics - Anfänger-Themen 0
L Konvertieren von String zu double?! Java Basics - Anfänger-Themen 6
V Operatoren Warum kommt bei double bei den Nachkommastellen irgendwann eine 2?! (1.20000000000002) Java Basics - Anfänger-Themen 5
geekex Double zu String umwandeln in einer Methode Java Basics - Anfänger-Themen 28
E Bruch erstellen - Von Int zu Double Ergebnis Java Basics - Anfänger-Themen 24
G Probleme beim casten von double zu int Java Basics - Anfänger-Themen 3
I Double.ParseDouble 2 Textfelder Java Basics - Anfänger-Themen 1
M JComboBox feste double Werte zu ordnen Java Basics - Anfänger-Themen 8
P Datentypen Kann ich bei double Komma statt Punkt eingeben? Java Basics - Anfänger-Themen 14
E Von Double zu Long umwandeln Java Basics - Anfänger-Themen 9
L Bei falscher Eingabe soll NaN zurückgegeben werden, Rückgabetyp jedoch double Java Basics - Anfänger-Themen 3
V Variablen Double später deklarieren Java Basics - Anfänger-Themen 7
V double = 1.34823e-300 Java Basics - Anfänger-Themen 5
W double*double error Java Basics - Anfänger-Themen 4
kilopack15 Mehr Nachkommastellen mit double Java Basics - Anfänger-Themen 14
T Input/Output Double und String als Eingabe einlesen Java Basics - Anfänger-Themen 9
J [Rundungsfehler bei Double] Grundkurs Java: Checke Lösungsweg nicht Java Basics - Anfänger-Themen 1
W In einer Function<Double, Double> undefinierte Rechenoperationen abfangen? Java Basics - Anfänger-Themen 3
T set Metode für Double Java Basics - Anfänger-Themen 6
Hijo2006 String to Double Java Basics - Anfänger-Themen 4
K Double Wert runden und in Int umwandeln Java Basics - Anfänger-Themen 7
A Kommafehler beim double einleseen korrigieren Java Basics - Anfänger-Themen 2
K Operatoren The Operator * is undefined for the argument type(s) double, String Java Basics - Anfänger-Themen 4
das_leon String zu double konventieren Java Basics - Anfänger-Themen 1
K Genauer als Double? Java Basics - Anfänger-Themen 4
T Double.parseDouble(args[0]) Java Basics - Anfänger-Themen 13
A Java Ungenauigkeit double Java Basics - Anfänger-Themen 6
B Methoden The method mirror(double[]) in the type Convolution is not applicable for the arguments (double) Java Basics - Anfänger-Themen 8
C Typumwandlung von int<-->double Java Basics - Anfänger-Themen 6
M Double Wert auf 2 Kommastellen runden Java Basics - Anfänger-Themen 2
S Regelabfragen aus Double-Array Java Basics - Anfänger-Themen 2
A Erste Schritte Double Wert aus String zu int Java Basics - Anfänger-Themen 2
P Rückgabe erflogt nicht als Double Java Basics - Anfänger-Themen 2
K Erste Schritte switch - Warum sind long/float/double/... nicht erlaubt? Java Basics - Anfänger-Themen 5
P scanner ein Double einlesen Java Basics - Anfänger-Themen 10
T Java double berechnung fehler Java Basics - Anfänger-Themen 2
S double[x] , double[y] zu Point[] points kopieren? Java Basics - Anfänger-Themen 15
G double in float umwandeln Java Basics - Anfänger-Themen 2
F double[] an andere Methode übergeben Java Basics - Anfänger-Themen 1
B Datentypen Test float und double speichern Zahlen nur ungefähr Java Basics - Anfänger-Themen 4
S Datentypen double - kommastellen abschneiden Java Basics - Anfänger-Themen 6
M int double int double Graph Java Basics - Anfänger-Themen 3
K ArrayList<Double> --> double[] array Java Basics - Anfänger-Themen 5
Z Double in komma und Punkt akzeptieren -> Robusteeingabe Java Basics - Anfänger-Themen 7
S Double und Gleitkommazahlen mit JUnit testen Java Basics - Anfänger-Themen 7
B Datentypen Multiplzieren mit double wird ungenau Java Basics - Anfänger-Themen 4
K Von einem Double wert nur die Zahl vor dem Komma verwenden Java Basics - Anfänger-Themen 9
F Double neu formatieren mit NumberFormat Java Basics - Anfänger-Themen 2
M Double-Ausgabe in JTextField fehlerhaft Java Basics - Anfänger-Themen 2
T Problem mit double-Formatierung Java Basics - Anfänger-Themen 3
M Double Zahl in Grad Zahl Java Basics - Anfänger-Themen 7
M Datentypen Ergebniss- Double to String- wird nicht angezeigt Java Basics - Anfänger-Themen 13
S Double mithilfe eines Scanners so einlesen, dass ich damit rechnen kann Java Basics - Anfänger-Themen 4
M Die Double-Variable rundet? Java Basics - Anfänger-Themen 1
llabusch Methoden Methoden überlagern - entweder int || double Java Basics - Anfänger-Themen 10
S Double, int, Berechnung Java Basics - Anfänger-Themen 3
K Datentypen Wertebereich float/double - Warum nicht hoch -1 Java Basics - Anfänger-Themen 6
A Double[] Array zahlen per Argument übergeben Java Basics - Anfänger-Themen 5
B Erste Schritte Addition von double in switch-Anweisung Java Basics - Anfänger-Themen 2
D Unterschied zwischen double und Double Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben