Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi if-Abfrage mit Extended - Trotz gleichheit False (https://www.delphipraxis.net/171459-if-abfrage-mit-extended-trotz-gleichheit-false.html)

Captnemo 7. Nov 2012 13:24

if-Abfrage mit Extended - Trotz gleichheit False
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,

mal wieder ein Phänomen, was ich mir so nicht erklären kann. Aber vielleicht könnt ihr mir auf die Sprünge helfen.

Ich habe eine Function, die verschiedene Werte auf gleichheit Prüfen soll.
Doch leider scheint das bei Datentyp Extended nicht zu klappen, obwohl laut Debugger der Wert gleich ist.

Ich habe mal einen Screenshot beigefügt, dann wird deutlich was ich meine. Der Code ist schrecklich, ich weiß. Ist nur für's debugging so geschrieben.

flipdascript 7. Nov 2012 13:29

AW: if-Abfrage mit Extended - Trotz gleichheit False
 
Der für die Anzeige aufbereitete Wert ist gleich. Der in den Variablen stehende Wert ist es nicht.
Für Vergleiche von Fließkommazahlen solltest Du CompareeValue aus der Math-Unit verwenden.

sahimba 7. Nov 2012 13:32

AW: if-Abfrage mit Extended - Trotz gleichheit False
 
Hi,

Die Fließkommazahlen sind aufgrund ihrer internen Darstellung nicht exakt gleich (irgendwo an der gefühlt 190.000 Nachkomastelle), auch wenn der Debugger dies so anzeigen mag. Verwende die Funktion CompareValue, welche hier eine (minimale) Toleranz berücksichtigt.
Siehe: http://www.delphibasics.co.uk/RTL.asp?Name=CompareValue

Cheers,
S.

stahli 7. Nov 2012 13:43

AW: if-Abfrage mit Extended - Trotz gleichheit False
 
Folgendes hatte ich mal zu dem Thema zusammen gesucht:


http://de.wikipedia.org/wiki/Rundungsfehler
http://de.wikipedia.org/wiki/Gleitkommazahl

Zitat:

Prüfung auf Gleichheit
Die im Abschnitt Dezimalzahlen genannte Einschränkung, dass viele Dezimalzahlen in Binärsystemen in Computern nicht exakt dargestellt werden können, hat beim Programmieren Auswirkungen auf Vergleiche zwischen Fließkommazahlen. Ein Beispiel in C soll dies verdeutlichen:
#include "stdio.h"
int main(){
if(.362*100. != 36.2)
printf("verschieden\n");

if(.362*100./100. != .362)
printf("auch verschieden\n");
return 0;
}
Obwohl die beiden Gleichungen und mathematisch korrekt sind, werden sie wegen der ungenauen Umrechnung ins Computer-Binärsystem falsch. Im Beispiel-Programm werden somit beide Ungleichungen als wahr angesehen.
Vergleiche müssen deshalb durch eine Abfrage ersetzt werden, ob die zu vergleichenden Werte im Rahmen einer erreichbaren Genauigkeit (meist Toleranz genannt) als gleich angesehen werden können.
Toleriert man beim Vergleich einen absoluten Fehler, lautet eine mögliche Formulierung .
Toleriert man beim Vergleich einen relativen Fehler, lautet eine mögliche Formulierung . Der zweite Fall muss meist noch mit der Sonderfallabfrage verbunden werden.
Sogar Zahlen mit exakt denselben Bitmustern und somit eigentlich exakt identischen Werten werden vom Rechner mit manchmal nicht als gleich angesehen. Das hat als Ursache die manchmal nicht identischen Formate im Speicher (Bsp.: Intel 64 Bit) und während einer Rechnung in der Gleitpunkteinheit (Bsp.: Intel 80 Bit). Wenn dieselben Bitmuster, die verglichen werden sollen, einmal aus dem Speicher und somit gerundet und einmal aus der FPU und somit mit der vollen Genauigkeit kommen, führt ein Vergleich zum falschen Ergebnis. Die Abhilfe ist dieselbe wie schon beschrieben.

Captnemo 7. Nov 2012 13:52

AW: if-Abfrage mit Extended - Trotz gleichheit False
 
Jepp, das wars ;-) Super, vielen Dank. Hätt ich jetzt gar nicht gedacht.

Da der eine Wert aus einer MSSQL-DB stamt, der zweite jedoch aus einer Textdatei umgesetzt wird, wärs jetzt mal interessant, wer mir den Unterschied an x-ten Stelle da reinschummelt....ich fürchte mal des SQL-Server.

Medium 7. Nov 2012 15:34

AW: if-Abfrage mit Extended - Trotz gleichheit False
 
Da schummelt keiner etwas rein - bzw. könnten sogar schon die Programme dafür "verantwortlich" sein, die diese Werte geschrieben haben. In Gänsefüßchen, weil letztlich immer nur die FPU, bzw. eigentlich die Bitbreite der FPU das wichtige ist. Die Ungenauigkeit ist im grundlegensten Prinzip der Fließkommarechnung begründet, und tritt immer und überall auf, wo Fließkommazahlen verwendet werden. Und jede einzelne Operation macht es schlimmer, so dass man (fast) sagen kann: Je mehr Rechenschritte eine Zahl durchlaufen musste, desto größer ist der Fehler im Vergleich zu einer hypothetischen Unendlich-Bit-FPU. Kommt noch Um- und Rückwandlung mit Strings dazu, wird es feierlich :). Da gibt's keinen Schuldigen*, das ist einfach so.

*) Man kann komplexe Rechnungen z.T. geschickt genug aufbauen um die Aufsummierung der Fehler zu minimieren, aber gemacht wird er eigentlich immer.

PS: Das ist eigentlich etwas, was jedem Entwickler/Informatiker am ersten Tag von Ausbildung/Studium beigebracht werden müsste. Und dann täglich wiederholt, wenn man zugrunde legt, wie oft die Frage hier auftaucht =)

Puke 7. Nov 2012 15:41

AW: if-Abfrage mit Extended - Trotz gleichheit False
 
Und wofür braucht man ultragenaue Rechnungen, die dann sowieso falsch sind?:shock:
Bisher runde ich auch Float-Zahlen zu Integer, die sind sowieso die einfachsten! :-D

p80286 7. Nov 2012 16:36

AW: if-Abfrage mit Extended - Trotz gleichheit False
 
Hast Du schon mal etwas von Logarithmen gehört?
oder Rechenschieber?
Fließkommazahlen arbeiten nach dem gleichen Prinzip, so genau wie nötig.
Wenn Du es ganz genau haben willst dann mußt Du eben Currency oder ähnlich Typen nutzen.

Gruß
K-H

Puke 7. Nov 2012 16:38

AW: if-Abfrage mit Extended - Trotz gleichheit False
 
wie genau muss es denn sein?
Wenn die 5. Zahl noch bedeutend ist. Tschuldigung
allerdings kann man sonst runden oder den Wert mal 1000 nehmen und in ein Integer runden.

Sir Rufo 7. Nov 2012 18:56

AW: if-Abfrage mit Extended - Trotz gleichheit False
 
Zitat:

Zitat von Puke (Beitrag 1190185)
wie genau muss es denn sein?
Wenn die 5. Zahl noch bedeutend ist. Tschuldigung
allerdings kann man sonst runden oder den Wert mal 1000 nehmen und in ein Integer runden.

Currency ist intern ein Int64 wo die letzten 4 Stellen als Nachkommastellen verwendet werden ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:19 Uhr.
Seite 1 von 3  1 23      

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