Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Single wert ist unterschiedlich obwohl gleich (https://www.delphipraxis.net/196763-single-wert-ist-unterschiedlich-obwohl-gleich.html)

EWeiss 17. Jun 2018 21:14


Single wert ist unterschiedlich obwohl gleich
 
Versuch 1:
Delphi-Quellcode:
const
  SCALE_DEFAULT = 0.68;
Ich weise diesen wert zu und schicke ihn an meine DLL.
Delphi-Quellcode:
gSprFace.GD_SetObjectScale(ID, SCALE_DEFAULT);


In der DLL jedoch kommt dieser wert an "0,68000000715"
Wenn ich nun vergleiche
Delphi-Quellcode:
if (rScale > SCALE_DEFAULT) then
dann wird mir True zurückgegeben logisch der wert aus der DLL ist mehr als 0.68 (Aber er wird zum weg in die DLL verändert) also Falsch!
Denn wie man sehen kann habe ich einen anderen übergeben.

Versuch 2:
Delphi-Quellcode:
const
  SCALE_DEFAULT = 0.68000000715;
Ich weise nun exakt diesen wert zu (der zur DLL verändert wird) und schicke ihn an meine DLL.
Delphi-Quellcode:
gSprFace.GD_SetObjectScale(ID, SCALE_DEFAULT);


In der DLL kommt dieser wert an "0,68000000715" den ich auch übergeben habe.
Wenn ich nun vergleiche
Delphi-Quellcode:
if (rScale > SCALE_DEFAULT) then


dann wird mir True zurückgegeben warum wenn beide werte gleich sind ?

Zwei Problem treten auf.

1. Schicke ich den ersten wert mit 0.68 dann wird dieser zu 0,68000000715 verändert
2. Schicke ich nun exakt diesen wert zu wird bei der Abfrage ebenfalls true zurück gegeben.

Kann ich nicht nachvollziehen.

gruss

gammatester 17. Jun 2018 21:22

AW: Single wert ist unterschiedlich obwohl gleich
 
Der Wert für 0.68 als Single ist 0.680000007152557373046875. Also ist er in der DLL richtig.

Wie ist rScale deklariert? Der Ausdruck `rScale > SCALE_DEFAULT` wird je nach Compiler als Double oder Extended ausgewertet.

Speichere die Differenz mal als Single und schau das Ergbenis an.

Wie gesagt: die Auswertung erfolgt mit Double/Extended, hier die Werte für Double
Code:
0.68000000715  -> 0.68000000714999997430965095190913416445255279541015625
0.68           -> 0.68000000000000004884981308350688777863979339599609375
und für Extended
Code:
0.68000000715  -> 0.68000000715000000000524243981558925042918417602777481079102
0.68           -> 0.68000000000000000000650521303491302660404471680521965026855

EWeiss 17. Jun 2018 21:27

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von gammatester (Beitrag 1405023)
Der Wert für 0.68 als Single ist 0.680000007152557373046875. Also ist er in der DLL richtig.
Wie ist rScale deklariert?

rScale ist natürlich als Single definiert.

Zitat:

Der Ausdruck `rScale > SCALE_DEFAULT` wird je nach Compiler als Double oder Extended ausgewertet
Was muss ich jetzt tun?
Hatte noch nie so ein Problem.

OK habe es selbst herausgefunden. Danke!

Delphi-Quellcode:
const
  SCALE_DEFAULT: single = 0.68;
Noch nie ein ähnliches Problem gehabt.

gruss

gammatester 17. Jun 2018 21:38

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von EWeiss (Beitrag 1405025)
Zitat:

Der Ausdruck `rScale > SCALE_DEFAULT` wird je nach Compiler als Double oder Extended ausgewertet
Was muss ich jetzt tun?
Hatte noch nie so ein Problem.

Versuch mal Folgendes:
Delphi-Quellcode:
tmpsingle := rScale - SCALE_DEFAULT;
if tmpsingle > 0 then ...
oder wahrscheinlich besser definiere SCALE_DEFAULT als single
Delphi-Quellcode:
const
  SCALE_DEFAULT: single = 0.68;

EWeiss 17. Jun 2018 21:40

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von gammatester (Beitrag 1405026)
Zitat:

Zitat von EWeiss (Beitrag 1405025)
Zitat:

Der Ausdruck `rScale > SCALE_DEFAULT` wird je nach Compiler als Double oder Extended ausgewertet
Was muss ich jetzt tun?
Hatte noch nie so ein Problem.

Versuch mal Folgendes:
Delphi-Quellcode:
tmpsingle := rScale - SCALE_DEFAULT;
if tmpsingle > 0 then ...

Ich habe es so gelöst.. Danke.
Delphi-Quellcode:
const
   SCALE_DEFAULT: single = 0.68;
gruss

gammatester 17. Jun 2018 21:45

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von EWeiss (Beitrag 1405027)
Ich habe es so gelöst.. Danke.
Delphi-Quellcode:
const
   SCALE_DEFAULT: single = 0.68;
gruss

Freut mich zu lesen, mein Edit hatte sich mit Deiner Antwort gekreuzt.

EWeiss 17. Jun 2018 21:51

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von gammatester (Beitrag 1405028)
Zitat:

Zitat von EWeiss (Beitrag 1405027)
Ich habe es so gelöst.. Danke.
Delphi-Quellcode:
const
   SCALE_DEFAULT: single = 0.68;
gruss

Freut mich zu lesen, mein Edit hatte sich mit Deiner Antwort gekreuzt.

Macht ja nichts ;)
Danke trotzdem.
Die kleine Abfrage hat bei mir 35% CPU Auslastung verursacht weil es immer true war.

gruss

jaenicke 17. Jun 2018 22:17

AW: Single wert ist unterschiedlich obwohl gleich
 
Wenn das an einer Stelle wichtig ist, würde ich immer zusätzlich zum Vergleich IsZero benutzen um mit einem genügend kleinen Epsilon die Gleichheit auszuschließen.

himitsu 18. Jun 2018 10:08

AW: Single wert ist unterschiedlich obwohl gleich
 
Single = 7-8 signifikante Dezimalstellen, also im Wost-Case nur 7.
Die erste Signifikante ist von links die erste Nicht-Null.

0.68000000715

Selbst Schuld, wenn du einen Wertebereich haben willst, der nichtmals Ansatzweise in den Datentyp passt.
Und selbst wenn, dann sind auch innerhalb der Signifikanten Rundungsfehler möglich, vor allem bei gewissen unendlich langen Werten ala 2/3.

Single hat einen 8 Bit-Exponent und eine Mantisse von 23 Bit Länge, inkl. einem virtuellen Bit, wenn der Exponent 0 ist, also 24.
2^24 = 16.777.215 = nicht ganz 8 Dezimalstellen (nur 1. bis 7. können alles von 0 bis 9 sein)

EWeiss 18. Jun 2018 10:56

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Selbst Schuld, wenn du einen Wertebereich haben willst, der nichtmals Ansatzweise in den Datentyp passt.
0.68 passt nicht rein?
Nun gut wenn du das sagst ist es wohl so.

Zitat:

Und selbst wenn, dann sind auch innerhalb der Signifikanten Rundungsfehler möglich, vor allem bei gewissen unendlich langen Werten ala 2/3.
Hallo ?
Und wer erstellt diese? Genau! Delphi.
Ich habe übergeben 0.68 und Delphi mach daraus deinen unendlich langen Werten 0.68000000715 lese doch bitte nochmal was ich geschrieben habe.

Zitat:

2^24 = 16.777.215 = nicht ganz 8 Dezimalstellen (nur 1. bis 7. können alles von 0 bis 9 sein)
Sage das den Entwicklern des Delphi Compiler nicht mir ;)
Wie gesagt.. Ich habe 0.68 übergeben und erwarte eigentlich das dieser wert auch berechnet wird.

gruss

gammatester 18. Jun 2018 10:57

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von himitsu (Beitrag 1405057)
Single = 7-8 signifikante Dezimalstellen, also im Wost-Case nur 7.
Die erste Signifikante ist von links die erste Nicht-Null.

0.68000000715

Selbst Schuld, wenn du einen Wertebereich haben willst, der nichtmals Ansatzweise in den Datentyp passt.
Und selbst wenn, dann sind auch innerhalb der Signifikanten Rundungsfehler möglich, vor allem bei gewissen unendlich langen Werten ala 2/3.

Und warum sollte 0.68 nicht in den Single-Bereich passen? Es ist nur nicht exakt darstellbar, ebenso wenig wie als Double oder Extended. Also ist das Gerede vom falschen Datentyp noch nicht mal 10% der Wahrheit.
Zitat:

Zitat von himitsu (Beitrag 1405057)
Single hat einen 8 Bit-Exponent und eine Mantisse von 23 Bit Länge, inkl. einem virtuellen Bit, wenn der Exponent 0 ist, also 24.
2^24 = 16.777.215 = nicht ganz 8 Dezimalstellen (nur 1. bis 7. können alles von 0 bis 9 sein)

Querfrage: Warum ist 0.000000000931322574615478515625 exakt als Single dastellbar, obwohl es 21 signifikante Stellen hat?

Wenn der Exponent 0 ist hat man subnormale Zahlen, und im Gegensatz zu Deiner Behauptung wird das signifikante Bit in dieser Situation gerade nicht versteckt!

Normalisierte Zahlen haben immer eine 24-Bit Mantisse bzw. Signifikand (falls Du Deine Info vom deutschen Wikipedia schau mal ins englische oder in den Standard IEEE754_2008 Tabelle 3.2).

EWeiss 18. Jun 2018 11:35

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Und warum sollte 0.68 nicht in den Single-Bereich passen?
Nun weil @himitsu es sagt.

Was ich nicht verstehe.. Warum hier der Compiler von Delphi wieder eine Extrawurst kreiert (Double oder Extended)
Definiere ich in C++ die gleiche Const dann gibt es so was nicht.

gruss

bernau 18. Jun 2018 11:39

AW: Single wert ist unterschiedlich obwohl gleich
 
Für Gleitkomma-Datentypen verwende ich mittlerweile (fast) immer Funktionen aus der Unit System.Math

IsZero oder Samevalue oder compareValue ist da dein Freund.

gammatester 18. Jun 2018 11:41

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von EWeiss (Beitrag 1405068)
Zitat:

Und warum sollte 0.68 nicht in den Single-Bereich passen?
Nun weil @himitsu es sagt.

Was ich nicht verstehe.. Warum hier der Compiler von Delphi wieder eine Extrawurst kreiert (Double oder Extended)
Definiere ich in C++ die gleiche Const dann gibt es so was nicht.

gruss

C++ rechnet wohl immer double (aber legt mich nicht fest).

Delphi-32-Bit rechnet intern mit extended.

Delphi-64-Bit via SSE immer als double.

EWeiss 18. Jun 2018 11:42

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von bernau (Beitrag 1405069)
Für Gleitkomma-Datentypen verwende ich mittlerweile (fast) immer Funktionen aus der Unit System.Math

IsZero oder Samevalue oder compareValue ist da dein Freund.

Ja warum es einfach machen wenn es auch umständlich geht.
Bleibt unverständlich für mich.

Zitat:

C++ rechnet wohl immer double (aber legt mich nicht fest).
Delphi-32-Bit rechnet intern mit extended.
Delphi-64-Bit via SSE immer als double.
Jo..
Ich habe schon Anwendungen in Sharp, VBNet, Vb6, C++ geschrieben
Nirgendwo habe ich je solche Probleme mit Single gehabt.

gruss

gammatester 18. Jun 2018 12:01

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von bernau (Beitrag 1405069)
IsZero oder Samevalue oder compareValue ist da dein Freund.

Das sind genau die Routinen für Leute, die keine/wenig Ahnung haben. Nach der simplen Methode liefert iszero(Planckkonstante)=true oder iszero(Gravitationkonstante)=true. Außerdem ist iszero für solche Feautures wie sinh(1e-20)=0 verantwortlich, wohingegen sin(1e-20) richtig = 1e-20 ist.
Delphi-Quellcode:
{$apptype console}
uses
  Math;
const
  g: single = 6.67e-11;
  h: extended = 6.63e-34;
begin
  writeln(iszero(g));
  writeln(iszero(h));
  writeln(sinh(1e-20));
  writeln(sin(1e-20));
end.
Code:
TRUE
TRUE
 0.00000000000000E+0000
 1.00000000000000E-0020
Man kann iszero etc richtig verwenden, aber dann kann man auch gleich seine Kenntnisse in die richtige Formulierung stecken. (Wer weiß schon auswendig, welche Default-Toleranz benutzt wird?)

himitsu 18. Jun 2018 12:03

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von EWeiss (Beitrag 1405071)
Ich habe schon Anwendungen in Sharp, VBNet, Vb6, C++ geschrieben
Nirgendwo habe ich je solche Probleme mit Single gehabt.

Und mit welchen Typen?

Je feiner der typ auflöst, also je größer er ist, um so kleiner werden die Problembereiche und so schwerer wird es sie zu treffen.



Beim Unwandeln dieser Werte in eine Textdarstellung sollte man niemals mehr als die signifikanten Stellen umwandeln, da alles danach quasi "zufällig" ist und diesen Rundungsfehler potenziert darstellt, je weiter man dahinter schaut.

Bei Vergleichen, vor allem Gleich, Kleiner-Gleich und Größer-Gleich, aber auch bei Kleiner und Größer muss man eben auch diese Rundungsfehler mit einbeziehen, was eben IsZero oder CompareValue machen (Delta).


Wer unbedingt genaue Werte braucht, muss auch die passenden Typen verwenden, wie z.B. Currency, BCD oder Dergleichen.


@gammatester: Wer mit solch kleinen Werten arbeitet, muß eben entweder das Delta anpassen oder eine andere Vergleichsmethode verwenden.

EWeiss 18. Jun 2018 12:08

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Beim Unwandeln dieser Werte in eine Textdarstellung
Welche Textdarstellung sorry ich sehe keine.

Delphi-Quellcode:
procedure RenderScale(WinHandle: HWND);
var
  bDone: BOOL;
  K, ID: Integer;
  CountMax: Integer;
  x, x1, y, y1, w, h: Integer;
  nScale: Integer;
begin

  bDone := false;
  CountMax := FaceList.Count - 1;

  ID := ID_FACE;

  for K := 0 to CountMax - 1 do
  begin
    if (ID <> gnFocusID) then
    begin
      rScale := gSprFace.GD_GetObjectScale(ID);
      if (ID = nHoverID) then
      begin
        if (rScale < 1.0) then
        begin
          bDone := true; // Wird hier true geschaltet und bleibt True wenn Single wert nicht stimmt.
          rScale := rScale + SCALE_STEP;

          if (rScale > 1.0) then
          begin
            rScale := 1.0;
            bDone := false;
          end;
          // Flare Animation
          gSprFace.GD_GetObjectBound(ID, w, h);
          nScale := (w - round(w * rScale)) div 2;

          gSprFace.GD_SetObjectVisibility(gnFocusFlare, true);

          gSprFace.GD_GetObjectXY(ID, x, y);
          x1 := x + 63 - nScale;
          y1 := nScale + 10;
          gSprFace.GD_SetObjectXY(gnFocusFlare, x1, y1);
          // Weiter mit ID
          gSprFace.GD_SetObjectScale(ID, rScale);
        end;
      end
      else
      begin
        if (rScale > SCALE_DEFAULT) then // stimmt dieser wert nicht dann ist bDone immer true und löst ein Repaint des gesamten Container aus.
        begin
          bDone := true;

          rScale := rScale - SCALE_STEP;
          if (rScale < SCALE_DEFAULT) then
          begin
            rScale := SCALE_DEFAULT;
            gSprFace.GD_SetObjectVisibility(gnFocusFlare, false);
            bDone := false;
          end;

          gSprFace.GD_SetObjectScale(ID, rScale);
        end;
      end;
    end;
    dec(ID);
  end;

  if (bDone) then
    gSprFace.GI_UpdateWindow(WinHandle, false); // Hier Problem wenn Single wert nicht stimmt = 35% CPU Auslastung.
end;
Zitat:

Und mit welchen Typen?
Beatwortet sich von selbst mit Single natürlich.
Wie der Compiler das innerhalb berechnet kann mir letztendlich egal sein.
Die dort verwendeten Compiler scheinen es richtig zu verstehen, Delphi hingegen nicht! (Extra Wurst halt) ;)

gruss

gammatester 18. Jun 2018 12:16

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von himitsu (Beitrag 1405076)
@gammatester: Wer mit solch kleinen Werten arbeitet, muß eben entweder das Delta anpassen oder eine andere Vergleichsmethode verwenden.

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.

Im übrigen ist 1e-20 geradezu erschreckend groß im Vergleich zu 1e-300 oder 1e-4000.

EWeiss 18. Jun 2018 12:27

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von gammatester (Beitrag 1405078)
Zitat:

Zitat von himitsu (Beitrag 1405076)
@gammatester: Wer mit solch kleinen Werten arbeitet, muß eben entweder das Delta anpassen oder eine andere Vergleichsmethode verwenden.

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.

Im übrigen ist 1e-20 geradezu erschreckend groß im Vergleich zu 1e-300 oder 1e-4000.

Sorry das ich das jetzt sage.. Eigentlich für mich egal.
Was zählt ist das ich eine Lösung wenn auch eine für mich unverständliche gefunden habe.
Ich bin nicht der Informatiker so wie ihr von daher zählt für mich das Ergebnis nicht das was dahinter steckt.

@gammatester
Danke nochmal für deine Hilfe und den Anstoß die Lösung zu finden.
PS: Interessant ist es aber trotzdem zu lesen.

gruss

bernau 18. Jun 2018 12:45

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von gammatester (Beitrag 1405078)
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.

gammatester 18. Jun 2018 13:34

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von bernau (Beitrag 1405086)
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.
Zitat:

Zitat von bernau (Beitrag 1405086)
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.

Zitat:

Zitat von bernau (Beitrag 1405086)
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)).

bernau 18. Jun 2018 13:53

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von gammatester (Beitrag 1405091)
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.

gammatester 18. Jun 2018 14:22

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von bernau (Beitrag 1405092)
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.

Luckie 18. Jun 2018 15:38

AW: Single wert ist unterschiedlich obwohl gleich
 
http://michael-puff.de/Programmierun...esskomma.shtml

bernau 18. Jun 2018 15:48

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von gammatester (Beitrag 1405095)
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

stahli 18. Jun 2018 16:20

AW: Single wert ist unterschiedlich obwohl gleich
 
@Luckie

Danke! Ich wusste noch so ungefähr, dass es da so ein Problem gab.
Gut, das mal aufzufrischen.

gammatester 18. Jun 2018 16:39

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von bernau (Beitrag 1405101)
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.
Zitat:

Zitat von stahli (Beitrag 1405109)
@Luckie
Danke! Ich wusste noch so ungefähr, dass es da so ein Problem gab.
Gut, das mal aufzufrischen.

Ja, offensichtlich der C-Compiler.

Sailor 18. Jun 2018 22:48

AW: Single wert ist unterschiedlich obwohl gleich
 
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.

gammatester 19. Jun 2018 08:19

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von Sailor (Beitrag 1405144)
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.
Zitat:

Zitat von Sailor (Beitrag 1405144)
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.
Zitat:

Zitat von Sailor (Beitrag 1405144)
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.

Rollo62 19. Jun 2018 14:40

AW: Single wert ist unterschiedlich obwohl gleich
 
Ich habe den Eindruck hier gibt es viele Lösungen, und jetzt wird krampfhaft nach dem passenden Problem gesucht :stupid:

EWeiss 19. Jun 2018 14:43

AW: Single wert ist unterschiedlich obwohl gleich
 
Zitat:

Zitat von Rollo62 (Beitrag 1405231)
Ich habe den Eindruck hier gibt es viele Lösungen, und jetzt wird krampfhaft nach dem passenden Problem gesucht :stupid:

Ich denke das es hier nur einen gibt der die Problematik wirklich versteht @gammatester
Das hat nichts mit suchen sondern wissen zu tun zumindest was ihn angeht.

gruss

p80286 19. Jun 2018 18:16

AW: Single wert ist unterschiedlich obwohl gleich
 
Also wenn ich es bisher richtig verstanden habe ist die Quintessenz:
Zitat:

neben der Tatsache, daß nicht alle reellen Zahlen Fließkommazahlen sind
oder anders nicht alle reellen Zahlen sind ohne Rundung(sfehler) als Fließkommazahl darstellbar.

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:02 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