AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Gleitpunktarithmetik - Diskrepanzen

Gleitpunktarithmetik - Diskrepanzen

Ein Thema von mumu · begonnen am 18. Dez 2005 · letzter Beitrag vom 20. Dez 2005
Antwort Antwort
Seite 2 von 2     12
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#11

Re: Gleitpunktarithmetik - Diskrepanzen

  Alt 19. Dez 2005, 15:47
Probiers aus.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#12

Re: Gleitpunktarithmetik - Diskrepanzen

  Alt 19. Dez 2005, 15:51
Lösung des Problems (markieren zum Lesen):


Die 0 ist als Float (Single, Double, Extended, ...) garnicht darstellbar . Für die 0 wird in der FPU ein separates Flag pro Register mitgeführt, und es ist so gut wie nie der Fall, dass eine Berechnung exakt 0 ergibt (eben wegen der üblichen Ungenauigkeit bei Floats). Deswegen gilt auch: Prüfe ein Float nie dirket auf Gleichheit mit 0! (bzw. überhaupt nicht direkt auf Gleichheit)

"Hier liegt Alles im grünen Bereich, sämtliche Zwischenergebnisse, Startwerte etc.
Oder vielleicht doch nicht?"

All diese Werte liegen folglich im Bereich, jedoch nicht der Wert mit dem verglichen wird - der 0!


-------------------
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#13

Re: Gleitpunktarithmetik - Diskrepanzen

  Alt 19. Dez 2005, 17:39
Einen hab ich noch: Kein Vergleich, keine 0, nur simples Addieren. Alle Zwischenergebnisse innerhalb des Wertebereiches.
Delphi-Quellcode:
Var
  x : Double;
  i : Integer;
begin
  x:=-1;
  For i:=1 to 10000 do x := x + 0.1;
  For i:=1 to 10000 do x := x - 0.1;
  memo.lines.add (FloatToStr(x));
end;
Was kommt raus (x + 10000*0.1 - 10000*0.1 = ?)
Bei Extended muss man ca. 500x öfter rechnen. Kann es sein, das auch die 0.1 nicht 100%ig akkurat dargestellt werden kann?
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#14

Re: Gleitpunktarithmetik - Diskrepanzen

  Alt 19. Dez 2005, 17:54
Das Ergebnis ist sicher nicht x 8)

Ich habe hier schon mal 0.2 binär dargestellt, und es wurde periodisch. Unter der Annahme dass eine halbierte periodische Zahl weiterhin periodisch ist, würde dies auch auf 0.1d zutreffen. Dadurch passt die Mantisse nicht in die dafür vorhandenen Bits (müssten ja unendlich viele sein ), und schon allein das hinterlegen des Wertes "0.1" in der FPU erzeugt eine Ungenauigkeit. Diese summiert sich auf, und wird aber nicht in gleicher Weise wieder abgezogen in der 2. Schleife! Ungenauigkeiten bei Floats haben so die Eigenschaft mit jeder weiteren Rechnung immer schlimmer zu werden als besser
Folglich wird das Ergebnis nachher x+-e heissen, wobei e eine beliebige kleine (nicht beliebig kleine! ) reelle Zahl ist, wenn nur ausreichend Zwischenschritte ausgeführt werden.
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#15

Re: Gleitpunktarithmetik - Diskrepanzen

  Alt 19. Dez 2005, 18:49
Ich finde das Thema rationale Zahlen in binärer Schreibweise ziemlich interessant, vor allem da es nicht im Schulstoff vorkommt (ganze binäre Zahlen schon in der 5.) und ich ohne Real/Double gar nicht wüsste, dass es so etwas gibt . Solche Zahlenkolonnen wie "01110100010" kommen einem ja bekannt vor, aber "11,010" ist ersteinmal doch etwas ungewohnt.
Folgendes lässt sich ja problemlos kompilieren:
Delphi-Quellcode:
begin
  x:=-0.5;
  while x<0.2 do begin
    if x=0 then
      memo.lines.add('[:-)')
    else
      memo.Lines.Add(FloatToStr(x));
    x := x+0.125;
    End;
end;
Besonders interessant finde ich die Lösung im .NET-Framework für genaue Fließkommazahlen: m * 10 ^ -e
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#16

Re: Gleitpunktarithmetik - Diskrepanzen

  Alt 19. Dez 2005, 20:49
dizzy: Du weisst mehr als ich. Ich wusste nur, das 0.1 nicht exakt dargestellt ist (periodisch)... Ich hab vor 25 Jahren diese Floating-Point Macken erlebt, als unser damalige Rechner (ein HP 9845) durch einen HP300 (mit Motorola 68k) ausgetauscht wurde und die Rechnungen statt mit BCD in der wesentlich schnelleren Floating-Point Arithmetik durchgeführt wurden.

Es ist auf jeden Fall ein sehr wichtiger Aspekt, wenn man weiss, das man zwar schnell rechnen kann, aber das Ergebnis mit einer gehörigen Portion Argwohn betrachten sollte. Bei komplexen Berechnungen, insbesondere iterativen Näherungen, kann sich der anfänglich marginale Fehler sehr schnell in den 1E-5er Bereich potenzieren, was dann gar nicht mehr lustig ist. Man muss dann z.B. die Vorgaben erst normalisieren, also in die Nähe von 1-100 bringen, um den Fehler wieder zu minimieren. Im Extremfall klappt das aber auch nicht.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#17

Re: Gleitpunktarithmetik - Diskrepanzen

  Alt 20. Dez 2005, 06:40
Extended geht von 3.6e10^-4951 bis 1.1e10^4932 und hat eine Manitisse von 64 Bit. Die Mantisse kann also nur 2^64 Zahlen korrekt darstellen * Bereich des Exponenten = 2^16 = 2^80.

Aus einem gesammten Zahlenbereich von 2^1024 können nur 2^80 Zahlen exakt in einem Extended gespeichert werden, das sind 0,00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00672 48730 95247 25964 69121 5039 Prozent
== 1/2^944.

Man kann also mit annähernd 100 Prozent davon ausgehen das eine Fließkommaberechnung immer "falsch" rechnet.

Extendend hat 10 Bytes = 10*8 = Speicherbereich 2^80. Der Exponent fasst 16 Bits = 2^16 und Mantisse 64 Bits = 2^64. Maximal speicherbar also 2^64 * 2^16 = 2^80, maximaler Wertebereich der Zahlen 2^(64 * 16) = 2^1024.
2^1024 / 2^80 = 2^944 Zahlen aus dem gesammten Wertebereich des Extended können nicht exakt gespeichert werden.Dabei ist es irrelevant ob man nur mit kleinen Zahlen annähernd 0.0 rechnet, der "Fehler" ist gleichverteilt.

Gruß Hagen
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#18

Re: Gleitpunktarithmetik - Diskrepanzen

  Alt 20. Dez 2005, 08:35
@negaH: So logisch einfach hab ich das noch nie gesehen.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz