Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - gleichheitproblem


buSC - So 31.01.10 17:24
Titel: gleichheitproblem
Liebe forumer

angenommen folgende Zeilen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
var i,flag:Integer;
  num,k,sum,step,zero:double;

begin
  sum:=0;
  zero:=0;
  num:=86;
  k:=num-zero;
  step:=k/10;
  for i:=1 to 10 do
   sum:=sum+step;
  if sum=k then Flag:=1;
  if sum<k then Flag:=2;
  if sum>k then Flag:=3;
  inc(i);
end;

das illustriert ein vefahren ,das im mein Program ausgerichtet worden ist,aber das Problem ist es ,dass bei mir der dritte Fall passiert, "Flag=3" . ist es ueberhaupt moeglich oder?
(wenn ich obengeschriebene Zeilen alleine ausfuehre ,passiert der zweite Fall.) wobei ich will dass der erste Fall passiert.

vielen Dank im Voraus :)

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt
Moderiert von user profile iconNarses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.


jaenicke - So 31.01.10 17:34

Auf Gleichheit zu testen bei Gleitkommazahlen wird nix aufgrund des Dualsystems, das im PC verwendet wird und das Dezimalzahlen daher nicht exakt darstellen kann. Da gibt es die Funktion Math.SameValue, die du dafür nutzen kannst.


Gausi - So 31.01.10 17:35

Das wird wieder das übliche Problem mit der Darstellung von Gleitkommazahlen im Rechner zu tun haben. Werte wie "Null Komma Eins" lassen sich zwar im Dezimalsystem "schön kurz" darstellen, aber nicht im Binärsystem des Rechners. man sollte daher niemals Float-Werte auf Gleichheit überprüfen, sondern immer mit einer gewissen Toleranz arbeiten. SameValue bietet sich dafür an. :D


buSC - Mo 01.02.10 17:01

erstmal vielen Dank an die beide Freunden, die mir geatwortet haben.

erstens:
wie ich verstanden habe,bei gleitkommazahlen kein exakte Gleichheit zu ueberpruefen ist.

zweitens:
wenn ich erste Zeile so aendere:
if SameValue(sum,k,0) then Flag:=1;
nach durchlauf von Zeile 12 ,Flag=1 ist
aber nochmal bei durchlauf von Zeile 13 wo sum<k ist, flag=2 wird.

Frage1:
ist es ueberhaupt moeglich ,dass der Fall sum>k ,passiert?

Frage2:
wenn ich null als dritte argument von "sameValue" function einfuege,ist es noch kein exakte Gleichheit oder?
und was ist der unterschied ,wenn ich die einfache gleichheit symbol verwende(d.h.: '=') und wenn ich null als dritte argument von sameValue verwende.

frage3:
ob es Gevrauch von aehnilchem funktion fuer die gleichheit-ueberpruefung von dezimalzahlen,wie " CompareValue" funktion noetig ist?
und wenn ja,wann kann ich bei gleichheits-Ueberprufung von dezimalzahlen,das symbol ,'=' ,verwende, und wann muss ich diese funktion verwende?

vielen Dank im Voraus

Moderiert von user profile iconNarses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.


JoelH - Mo 01.02.10 17:14

AFAIK Ordinale Typen kannste mit = vergleichen, sowie Currency-Werte. Alle anderen realen Typen nicht.


ALF - Mo 01.02.10 17:58

Du kannst aber folgendes machen, Vorzeichen Prüfen

Delphi-Quelltext
1:
2:
3:
4:
5:
 if (sum - k) = 0 then Flag := 0
 else
 if (sum - k) > 0 then Flag := 1
 else
 if (sum - k) < 0 then Flag := 2;


wenn ich es noch so in erinnerung habe :wink:

Gruss Alf


buSC - Mi 03.02.10 17:59

Danke an alle Freunde fuer Ihre Antworte,

2 wichtige Frage fuer mich waeren:
erste:
bei Gleichheitstest von Gleitkommazahlen ,ist es ueberhaupt logisch der symbol "=" zu verwenden ,oder ist es ein muss immer die Funktion "math.sameValue" zu verwenden?

zweite:
wie erklaert sich der gleiche Fall bei dezimalzahlen?

ich ware dankbar ,wenn ich die beide Antworten wissen duerfte.

danke im Voraus

:)

Moderiert von user profile iconNarses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.


ALF - Mi 03.02.10 18:31

Kurz und simple
Das Dualsysthem kennt keine Kommastellen.
Um einen Vergleich auf '=' zumachen, müsste die Funktion, die ganzZahl vor dem Komma auf 0 testen und die stellen nach dem Komma ebenfals auf 0 testen. (ganz simple ausgedrückt) und dies wird in der Funktion auf '=' nicht gemacht.
Die Funktion "math.sameValue" wurde desahlb implementiert weil sie es dann so macht.

und Ganzahl ist ja wohl klar.

Darum habe ich ja oben mal ein altes Beispeile angebracht wie es auch noch geht!

Gruss ALf


Gausi - Mi 03.02.10 19:29

user profile iconALF hat folgendes geschrieben Zum zitierten Posting springen:
Kurz und simple
Das Dualsysthem kennt keine Kommastellen.
Um einen Vergleich auf '=' zumachen, müsste die Funktion, die ganzZahl vor dem Komma auf 0 testen und die stellen nach dem Komma ebenfals auf 0 testen. (ganz simple ausgedrückt) und dies wird in der Funktion auf '=' nicht gemacht.
Die Funktion "math.sameValue" wurde desahlb implementiert weil sie es dann so macht.

Öhm, das ist ziemlicher Quatsch, würde ich mal sagen. Der Vergleich mit "=" überprüft auf Gleichheit. Und diese Überprüfung liefert ein falsches Ergebnis, wenn es zu Rundungsfehlern kommt. Beispiel im Dezimalsystem:


Quelltext
1:
3 * 2/3 "=" 3 * 0.6667 "=" 2,0001                    


Im Dualsystem kommt es an anderen Stellen zu ähnlichen Effekten.


ALF - Mi 03.02.10 23:52

Ich bezog das doch auf den Rechner/PC, mit dem Dualsysthem. :cry: oder war es das Binärsysthem !?
Den der kennt wirklich keine Komma stelle. 8)

Oder ich habe die Fragestellung halt nicht verstanden!?. :oops:

So wie ich aber weiss, spielt es keine Rolle, bei
k = s
k > s
k < s
wie oder mit was das Ergebnis von k und s zustande kam.

Es sei denn, ich will wissen, ab wann es zu unterschiedlichen Ergebnissen kommt.
wie Dein Beispiel es zeigt! user profile iconGausi

Hab mich vielleicht blöd ausgetrückt :roll:
Gruss ALf


Kha - Do 04.02.10 01:19

user profile iconALF hat folgendes geschrieben Zum zitierten Posting springen:
Ich bezog das doch auf den Rechner/PC, mit dem Dualsysthem. :cry: oder war es das Binärsysthem !?
Dasselbe in Grün. Ebenso wie x > y und x-y > 0 ;) .

user profile iconALF hat folgendes geschrieben Zum zitierten Posting springen:
Den der kennt wirklich keine Komma stelle. 8)
Sorry, aber die Aussage ist immer noch Quatsch bzw. hat überhaupt nichts mit dem Problem hier zu tun. Es ist alles eine Frage der Kodierung - oder würdest du behaupten, der PC kenne auch kein Minus und deshalb gelte 2 = -2?

user profile iconALF hat folgendes geschrieben Zum zitierten Posting springen:
So wie ich aber weiss, spielt es keine Rolle, bei
k = s
k > s
k < s
wie oder mit was das Ergebnis von k und s zustande kam.
Eben doch. Sobald nicht mehr wie in der puren Mathematik mit unendlicher Genauigkeit gerechnet wird, muss im Prinzip für jeden Schritt eine Fehlerrechnung aufgestellt werden.