AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Single wert ist unterschiedlich obwohl gleich
Thema durchsuchen
Ansicht
Themen-Optionen

Single wert ist unterschiedlich obwohl gleich

Ein Thema von EWeiss · begonnen am 17. Jun 2018 · letzter Beitrag vom 19. Jun 2018
Antwort Antwort
Seite 3 von 4     123 4      
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.268 Beiträge
 
Delphi 11 Alexandria
 
#21

AW: Single wert ist unterschiedlich obwohl gleich

  Alt 18. Jun 2018, 12:45
Sag ich ja: Wenn man keine Ahnung hat benutzt man die Default-Werte und macht (wie Borland/Emba beim sinh) haarsträubende Fehler. Wenn man weiß, wo die Probleme sind, dann braucht man diese Routinen nicht.
Nur weil man Funktionen ggf. falsch anwenden kann, sind diese trotzdem nicht per se schlecht.

Und ein IsZero(Value1) oder SameValue(Value1,Value2) ist m.E. besser zu lesen als jede hingeklatsche Berechnung, die ein Epsilon berücksichtigt.

Oder gib mal ein Beispiel, wie du zwei Gleitkommazahlen vergleichst. Man lernt ja nie aus.
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#22

AW: Single wert ist unterschiedlich obwohl gleich

  Alt 18. Jun 2018, 13:34
Nur weil man Funktionen ggf. falsch anwenden kann, sind diese trotzdem nicht per se schlecht.
Habe ich auch nie behauptet. Was ich gesagt habe, ist, daß sie überflüssig sind und zu Fehlern verleiten, weil gedacht werden könnte, man habe die Probleme der Fließkommaarithmetik damit magisch in den Griff bekommen.
Und ein IsZero(Value1) oder SameValue(Value1,Value2) ist m.E. besser zu lesen als jede hingeklatsche Berechnung, die ein Epsilon berücksichtigt.
Also für mich ist value1=0 oder value1=value2 viel besser lesbar und überhaupt nicht hingeklatscht. Über die Verwantwortung der Programmiers, ob die eine oder die andere Formulierung angemessener ist, wird damit nichts gesagt. Nochmal zu Errinnerung: mit welchem Default-Epsilon arbeitet iszero? (wenn Du es nicht weißt, solltest Du besser die Finger davon lassen). Ich sehe jedenfalls keine Sinn darin, dass const s: single = 0.0001 gleich Null sein soll (gerade mal 1/10 Promille) oder daß iszero(0,-0.00001) ungleich Null liefert.

Oder gib mal ein Beispiel, wie du zwei Gleitkommazahlen vergleichst. Man lernt ja nie aus.
Das Problem ist doch nicht das Vergleichen von Fließkommazahlen, die sind immer exakt und genau definiert. Ein Problem (neben der Tatsache, daß nicht alle reellen Zahlen Fließkommazahlen sind) ist, daß im Laufe von Rechnungen sich Rundungsfehler akkumulieren können, wenn man keine stabilen Algorithmen/Methoden benutzt. Es gibt ein spezielles Fach für solche Sachen (Numerische Mathematik, 'Scientific Computing'), hier erhält Abschätzungen, wie sich Eingangsfehler und Ausgangsfehler verhalten. Erst wenn man die Fehlerschranken der Methode kennt, kann man sinnvoll über die Toleranzen reden.

Leider ist es so, daß es keine Patentlösung gibt, und es nicht hilft, Schulbuchformeln zusammenzustellen und manchmal ein iszero etc einzufügen.

Hier das schon genannte Beispiel aus Math
Delphi-Quellcode:
function Sinh(const X: Extended): Extended;
begin
  if IsZero(X) then
    Result := 0
  else
    Result := (Exp(X) - Exp(-X)) / 2;
end;
Richtiger wäre, if IsZero(X) then Result := x, weil ja für kleine x die Maclaurinreihe für sinh(x) = x +x^3/6 + ... ist. Damit verschenkt man allerdings viel, da iszero hier mit 1e-16 arbeitet. Viel besser und lesbarer ist if abs(x) < 1e-9 then Result := x.

Auch der Rest ist Katastrophe. Warum soll man Exp zweimal aufrufen? Vielleicht um noch ein paar Rundungsfehler mehr zu machen? Entweder ist x so groß, daß exp(-x) vernachlässigbar ist, oder man benutzt exp(-x) = 1/exp(x). Ganz abgesehen davon, daß diese Schulbuchformel instabil ist da anfällig für katastrophale Auslöschung (sie liefert zB 0.999999996004197E-12 statt 1E-12 für sinh(1e-12)).

Geändert von gammatester (18. Jun 2018 um 13:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.268 Beiträge
 
Delphi 11 Alexandria
 
#23

AW: Single wert ist unterschiedlich obwohl gleich

  Alt 18. Jun 2018, 13:53
Also für mich ist value1=0 oder value1=value2 viel besser lesbar und überhaupt nicht hingeklatscht.
Aber der direkte Vergleich von Gleitkommazahlen ist eben ein NoGo. Genau damit fällt man doch auf die Nase. Du weist doch nicht wie die Zahlen entstanden sind. Ggf. durch komplexe Berechnungen. Dann ist ein value1=0 zufällig mal False, obwohl es true sein sollte. Das Gleiche gilt für value1=value2.

Diese Schreibweise ist natürlich schöner. Bei Integer kein Problem. Aber nicht bei Gleitkommazahlen.
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#24

AW: Single wert ist unterschiedlich obwohl gleich

  Alt 18. Jun 2018, 14:22
Aber der direkte Vergleich von Gleitkommazahlen ist eben ein NoGo. Genau damit fällt man doch auf die Nase. Du weist doch nicht wie die Zahlen entstanden sind. Ggf. durch komplexe Berechnungen. Dann ist ein value1=0 zufällig mal False, obwohl es true sein sollte. Das Gleiche gilt für value1=value2.
NoGo sagt wer? Die gleichen Leute, die mit SameValue/Iszero arbeiten und nicht wissen, was sie da programmiert? Wieso fällt man mit if Pi=3 auf die Nase? Ein Kompiler, der da true liefert, gehört die Tonne.

Zum Vergleich auf 0. Hier ist doch überhaupt kein Problem beim direkten Vergleich, wobei iszero für kleine Werte fehlerhaft ist. Ich kann mich an keine Rechnung errinnern, wo 'zufällig' 0 herrauskommt, normalerweise hat man dann einen Fehler gemacht. Das Problem ist eher andersherum, bei machen Rechnungem würde man 0 erwarten, aber es komment nicht, wie zB 1-10*(1/10) oder cos(Pi/2).

Im übrigen will ich Dich von Deiner festgefaßten Meinung nicht abbringen, und sehe die Sache hier als erledigt an.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#25

AW: Single wert ist unterschiedlich obwohl gleich

  Alt 18. Jun 2018, 15:38
http://michael-puff.de/Programmierun...esskomma.shtml
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.268 Beiträge
 
Delphi 11 Alexandria
 
#26

AW: Single wert ist unterschiedlich obwohl gleich

  Alt 18. Jun 2018, 15:48
Im übrigen will ich Dich von Deiner festgefaßten Meinung nicht abbringen, und sehe die Sache hier als erledigt an.
Darum geht es ja gar nicht. Ich will dich auch nicht von deiner Meinung abbringen. Aber viele sind schon auf diese Sache reingefallen. Und das hat nichts mit Blödheit zu tun.

Es gibt auch viele die mitlesen. Und wenn du schreibst, dass das direkte Vergleichen zweier Gleitkommazahlen kein Problem ist, dann führst du diese Leute auf's Glatteis.


Beispiel:

Delphi-Quellcode:
var
  value1: double;
  value2: double;
begin
  value1 := 1.23;
  value2 := 1.23;
  writeln(value1); // 1.23000000000000E+0000 -> Debugger zeigt 1.23 an
  writeln(value2); // 1.23000000000000E+0000 -> Debugger zeigt 1.23 an
  writeln(value1 = value2); // True
  value1 := sqrt(value1);
  writeln(value1); // 1.11905365064094E+0000
  value1 := Sqr(value1);
  writeln(value1); // 1.23000000000000E+0000 -> Debugger zeigt 1.23 an
  writeln(value1 = value2); // False -> Aber der Debuger zeigt für Value1 und Value2 den Wert 1.23 an. Suchst du dir halt den Wolf ;-)
  writeln(samevalue(value1 , value2)); //True
  value1 := value1-value2;
  writeln(value1); -2.22044604925031E-0016 // Erst hier fällt auf, dass es einen minimalen (ab der 16. Kommastelle) Unterschied gibt
  writeln(value1 = 0); // False
  writeln(IsZero(value1)); // True
  readln;
end.
Hier gibt der direkte Vergleich der Zahlen ein "False"


Anderes Beispiel:

Delphi-Quellcode:
var
  value1: double;
  value2: double;
begin
  value1 := 4;
  value2 := 4;
  writeln(value1); // 4.00000000000000E+0000
  writeln(value2); // 4.00000000000000E+0000
  writeln(value1 = value2); // True
  value1 := sqrt(value1);
  writeln(value1); // 2.00000000000000E+0000
  value1 := Sqr(value1);
  writeln(value1); // 4.00000000000000E+0000
  writeln(value1 = value2); // True
  writeln(samevalue(value1 , value2)); //True
  value1 := value1-value2;
  writeln(value1); // 0.00000000000000E+0000
  writeln(value1 = 0); // True
  writeln(IsZero(value1)); // True
  readln;
end.
Hier gibt der direkte Vergleich "True"

Für mich ein inkonsistentes Verhalten, was aber logisch ist wenn man die Internas berücksichtigt. Dennoch ist dieses Verhalten meist nicht gewünscht und mit "SameValue" kann man dies durch berücksichtigen des Epsilon umgehen
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#27

AW: Single wert ist unterschiedlich obwohl gleich

  Alt 18. Jun 2018, 16:20
@Luckie

Danke! Ich wusste noch so ungefähr, dass es da so ein Problem gab.
Gut, das mal aufzufrischen.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#28

AW: Single wert ist unterschiedlich obwohl gleich

  Alt 18. Jun 2018, 16:39
Es gibt auch viele die mitlesen. Und wenn du schreibst, dass das direkte Vergleichen zweier Gleitkommazahlen kein Problem ist, dann führst du diese Leute auf's Glatteis.
Inwischen habe ich die neuen Versionen von AMath/DAMath und MPArith hochgeladen und deshalb wieder etwas mehr Zeit. Vielleicht sollten wir allerdings einen eigenen Thread aufmachen oder ein Moderator splittet diesen.

Ich will niemanden auf Glatteis führen, und jeder mag iszero/samevalue benutzen. Nur bitte: der direkte Vergleich kann gar kein Problem sein, weil iszero/samevalue genau solche macht:
Delphi-Quellcode:
  if Epsilon = 0 then
    Epsilon := ExtendedResolution;
  Result := Abs(A) <= Epsilon;
Wie man sieht, zwei direkte Vergleiche. Ich sage nur, daß jeder das auch flexibler und angemessener direkt machen kann.

Zu Deinem Bespiel sqr(sqrt(2)) <> 2 und Luckies 69.82 <> 69.2 + 0.62. Das Problem ist wieder einmal die nicht exakte Darstellbarkeit, hier von sqrt(2) und allen Luckischen Zahlen (und ein C-Compiler-Problem?)

Was man sich merken sollte.
  • Nicht jede reelle Zahl ist exakt als Fließkommazahl f*2^x darstellbar mit 0 < f < 2^p und x innerhalb gewisser Grenzen.
  • Jede Fließkommazahl ist genau definiert. Ein reelle Zahl wird durch Rundung auf eine FKZ abgebildet.
  • Die Grundoperation verarbeiten die exakten FPZ wie mit unendlicher Genaugkeit und anschließender Rundung.
  • Dabei werden naturgemäß Rundungsfehler gemacht, die genau abgeschätzt werden können.
Hier Luckies float-Zahlen, d.h. single
Code:
69.2   -> 69.1999969482421875
0.62   -> 0.62000000476837158203125
69.82  -> 69.81999969482421875
Addiert man nun die beide exakten Singles, so erhält man 69.1999969482421875 + 0.62000000476837158203125 = 69.81999695301055908203125. Das wird nun zum nächsten Single gerundet und ergibt 69.81999969482421875 was genau dem Single-Wert von 69.82 entspricht.

Ich weiß, zwar nicht was für einen C-Compiler er benutzt hat, aber alle Delphi/Freepascal-Versionen liefern true als Ausgabe von
Delphi-Quellcode:
{$apptype console}
var
  a,b,c,d: single;
begin
  a := 69.2;
  b := 0.62;
  c := a + b;
  d := 69.82;
  writeln(c=d);
end.
@Luckie
Danke! Ich wusste noch so ungefähr, dass es da so ein Problem gab.
Gut, das mal aufzufrischen.
Ja, offensichtlich der C-Compiler.

Geändert von gammatester (18. Jun 2018 um 16:48 Uhr)
  Mit Zitat antworten Zitat
Sailor

Registriert seit: 20. Jul 2008
Ort: Balaton
112 Beiträge
 
Delphi 2010 Professional
 
#29

AW: Single wert ist unterschiedlich obwohl gleich

  Alt 18. Jun 2018, 22:48
Sorry, muß mal noch kurz meinen Senf dazugeben. Der Computer rechnet nicht mit reellen Zahlen, sondern mit rationalen Zahlen. Das Problem ist, daß wegen der begrenzten Stellenzahl nur die wenigsten rationalen Zahlen überhaupt darstellbar sind. Wer mit dem Rechner tatsächlich rechnet im traditionellen Sinn, dem sei The Art of Programming, vol. 1 von Knuth dringend ans Herz gelegt. Leider wird das Thema auch während der Ausbildung nur stiefmütterlich behandelt.
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#30

AW: Single wert ist unterschiedlich obwohl gleich

  Alt 19. Jun 2018, 08:19
Sorry, muß mal noch kurz meinen Senf dazugeben. Der Computer rechnet nicht mit reellen Zahlen, sondern mit rationalen Zahlen.
'Der Computer' ist was? Manche Programme rechnen symbolisch mit rationalen Zahlen, nativ ist iA nur Integer- und Fließkommaarithmetik vorhanden, alles andere ist, wenn überhaupt, nur mit Software implementiert.
Das Problem ist, daß wegen der begrenzten Stellenzahl nur die wenigsten rationalen Zahlen überhaupt darstellbar sind.
Richtig: Die Darstellung von rationalen Zahlen braucht keine Stellen nach dem Komma, da sie ja Paare von Integer sind. Und genau da liegt ein viel größeres Problem: Die Größe von Zähler und Nenner (und damit ihr Speicherbedarf) wächst dramatisch schnell, selbst wenn man nach jeder Operation den GGT von Zähler und Nenner herauskürzt: Nimm mal Dein bevorzugtes CAS und rechne einfache Sachen wie (1+3/100)^40 oder Summe(1/n^2, n=1..100) aus, von etwas komplizierteren Sachen ganz zuschweigen. Also ohne Langzahlarithmetik eignet sich die Simulation von rationaler Arithmetik nur für Spielkram oder Übungsaufgaben. Aber wie gesagt, für spezielle Anwendungen angemessen mit Programmen wie Mathematica oder Maple.

Allerdings muß man beachten, daß die Operationen der Rational-Arithmetik dann nicht mehr in konstanter Zeit abgewickelt werden können, sondern mit Zähler- und Nennerlänge ansteigen, auch wenn Bruchwert sich nur wenig ändert, siehe das Summenbeispiel.
Wer mit dem Rechner tatsächlich rechnet im traditionellen Sinn, dem sei The Art of Programming, vol. 1 von Knuth dringend ans Herz gelegt. Leider wird das Thema auch während der Ausbildung nur stiefmütterlich behandelt.
Dem kann man nur zustimmen, obwohl wichtiger erscheint mir doch da Vol 2. Kapitel 4, es sei denn, Du willst alles in MIX programmieren.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


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 06:51 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