Gleich ist kleiner

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Gleich ist kleiner

Beitrag von Manfred »

Hi,

zum Jahreswechsel noch eine kleine Freude:

zwischendurch passiert folgendes:

Code: Alles auswählen

IF oUmsatz:nGegeben < oUmsatz:nSumme
    lErfolg := .F.
ENDIF
Xbase++ behauptet einfach das :ngegeben < als :nSumme ist und dass obwohl beide Werte gleich sind.

Aber natürlich nicht immer und bei bestimmten Werten, sondern nur mal so zwischendurch.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

RE Kleiner gleich

Beitrag von Rolf Ramacher »

Hi Manfred,

kann es vielleicht sein, daß nsumme in den entsprechenden Fällen mit anderen/falschen Werten befüllt wird.
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi,

sorry, ich habe vergessen zu erwähnen, das der Debugger angezeigt hat, das gleiche Werte darin stehen.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Hallo Manfred,
von nichts kommt nichts.

Du solltest in Deinem Falle die Zuweisungen der Membervariablen überprüfen. Hier liegt mit Sicherheit die Fehlerursache.

Viele Grüße
Olaf
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

das ist ein altes Problem, du siehst z.B. das:

1. 4,50
2. 4,50

und meinst, dass die Variablen gleich sind.
Tatsächlich ist aber 1. intern 1,4500001 und 2. 1,4499999

Um bei solchen Vergleichen das zu bekommen wass
du wohl möchtest, mußt du mit ROUND() arbeiten:

z.b.
if Round(x,2) < Round(y,2) // Genauigkeit auf 2 Dezimalstellen

alle Bildschirmausgaben sind irgendwie gerundet.
Bei Rechnungssummen mit errechneten Zeilenpositionen muss man auch
die Zwischenergebnisse immer runden, sonst kann es sein, dass die Summe unten (mathematisch korrekt, da mit genauen Zwischenwerten berechnet) um einige Cent von der Summe abweicht, die man manuell beim Addieren der Zeilen erhalten würde.
Zuletzt geändert von brandelh am Do, 28. Dez 2006 12:25, insgesamt 2-mal geändert.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Olaf,

das verstehe ich jetzt nicht wirklich. Das Problem taucht in ein und demselben Programmabschnitt sporadisch auf und ist nicht nachvollziehbar.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Hubert,

das hatte ich auch anfangs vermutet. Da ich aber nur mit Geldbeträgen arbeite, die unterste Rechenoperationen erfordern, sprich es werden nur Beträge genommen, die 2stellig nach dem Komma sind, es wird nur addiert und sonst nichts, frage ich mich wo soll da ein Rundungsfehler auftauchen?

Es sieht folgendermaßen aus. Das Programm ermittelt einen Betrag, der Euro und Cent hat. Dann wird der gegebene Betrag eingegeben und der ist dann ebenfalls genauso hoch, wie der, der errechnet wurde. Es wird nur zusammengezählt. Es dürfen dabei keine Rundungsfehler auftauchen.

1,45 + 1,45 sind 2,90 und nicht 2,90000001 oder 2,89999999. Alles andere würde ich jetzt hier nicht verstehen.

PS: außerdem wollte ich hier nur sagen: Falls einer auch so ein merkwürdiges Problem haben sollte, die Person träumt nicht, es scheint sowas zu geben.

Ich lasse mich aber gerne belehren, aber nachvollziehbar.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Ich wollte sagen, dass die Fehlerursache wohl nicht im implementierten Vergleichsoperator liegt.

Hubert hat Dir vieleicht ein mögliche Fehlerursache aufgezeigt.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

ein Computer rechnet nicht mit dem Dezimalsystem wie wir, sondern mit dem Dualsystem. Darum sind ja auch 1 KB keine 1000 Byte sonden 1024 (außer bei Festplattenangaben vom Hersteller ;) ).

Es gibt Compiler, die verschiedene Zahlentypen abdecken können, z.B. Integerwerte (nur ganze Zahlen, ja nach Art mit oder nur ohne Vorzeichen).

Xbase++ (wie auch Clipper und dBase) kennen nur einen Typ mit Nachkommastellen !

Die Zahl 1 dezimal entspricht 1 im dualen System, somit müssten diese intern wie extern gleich dargestellt werden, aber 4,50 sieht intern ganz anders aus! Wenn nun ein Zwischenergebnis herauskommt, dass unter dezimal glatt aufgeht, ist es intern fast immer nur ein Näherungswert.

Dein Programm wird häufig im Näherungswert über der < Abfrage liegen und du denkst da funktioniert es richtig, Tatsache ist aber, dass dies nur ein Zufall ist. Natürlich könnte auch noch eine andere Ursache an einer anderen Stelle dafür verantwortlich sein, aber das Problem mit den Fließkommazahlen und deren Genauigkeit bleibt !

Spezielle Finanzprogramme oder Compiler die sich sowas nicht leisten können (wollen) kennen einen Datentyp Währung mit simmulierten 2 Nachkommastellen. Intern wird dieser entweder über Ganzzahltypen mit riesigem Wertebereich oder gleich per 'Text' berechnet. Die Tools hatten Funktionen, die eine Zahl in einem String an einer Stelle erhöhen konnten.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Hubert,

also soll ich davon ausgehen, das 1,45 + 1,45 nicht unbedingt immer 2,90 ergeben? Hm, fällt mir schwer zu glauben. Es werden feste Werte vorgegeben, die IMMER nur 2stellig sind.

Aber Du bringst mich da auf eine Idee. Ich bin gleich wieder da......
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9361
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Beitrag von Tom »

Code: Alles auswählen

x := 1.45
y := 1.45
? x < y // Antwort .F.
? 2.90 < x+y // Antwort .F.
x := (x/9)*9
? x // Antwort 1.45
? x < y // Antwort .T. !!!
? Str(x,19,9) // Antwort 1.450000000
Es ist Fließkomma. Die Darstellung ist immer gerundet, aber die Repräsentation der Zahlen gleicht sich nicht mehr.
Herzlich,
Tom
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Na super,

jetzt läßt der Fehler sich nicht mehr reproduzieren.
Wenn ich allerdings von der Rundungsungenauigkeit ausgehen muß/soll, dann darf ich doch davon ausgehen, des dieser Fehler bei jedem identischen Vorgang wieder auftreten müßte? Also, wenn es wieder passiert, dann werde ich exakt die gleichen Buchungen wiederholen und dann mal schauen, ob der Fehler immer wieder auftaucht.

Ihr hört noch von mir.....
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9361
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Beitrag von Tom »

Hallo, Manfred.

Wenn man zum Beispiel mit Brutto-/Nettobeträgen arbeitet, mal Mehrwertsteuer hinein und dann wieder herausrechnet, hilft es, bei Vergleichsoperationen nicht mehr auf die Variable selbst, sondern einen formatierten Ausgabewert zurückzugreifen. String-Operationen arbeitet beim Vergleich von Zahlen analog.

Code: Alles auswählen

lErfolg := IF(Str(x,19,9)<Str(y,19,9),.T.,.F.)         
Herzlich,
Tom
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Tom,

ich verstehe das schon alles, was hier erwähnt wird.

Aber bei einfachen Additionen, darf sowas nicht passieren. Es wird weder geteilt, noch multipliziert, noch gibt es irgendeinen Rest, der gerundet wird. Es bleibt bei 1,45 + 1,45 + 3,32 und das ergibt nach meinem Verständnis 6,22 und sonst nichts.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hi Manfred,

das sind die Tücken der Gleitkommazahlen.

1.45 ist dezimal "rund", hat in binärer Darstellung aber unendlich viele Nachkommastellen. Die werden im Numerikprozessor zwangsläufig irgendwo abgeschnitten. Also 1.45 + 0 = 1.4500000476837158 :wink:

Viele Grüße
Günter
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi,

](*,) :pukeleft: :boxing: brushteeth :blob6: :angry8: :banghead: :binky:

Leute vergesst allen Scheiß, den ich hier geschrieben habe. Danke Tom für den Hinweis mit den Nettobeträgen.

Ich habe nochmals nachgesehen. Ich habe eine Rabattklausel drin, die teilt durch 100. Da ich aber keinen Rabatt gegeben habe bei meinen Test, aber trotzdem geteilt und multipliziert wurde, ist jetzt alles klar. (blöde UDF´s, die man übersieht)

PS: Ich wollte ja nur die 10.000 voll machen........ (Was mir auch beinahe gelungen wäre.)
Zuletzt geändert von Manfred am Do, 28. Dez 2006 13:16, insgesamt 1-mal geändert.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Es lebe das Xbase Forum von Tom.

Ist mir alles peinlich.....
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9361
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Beitrag von Tom »

Hallo, Manfred.
Ist mir alles peinlich.....
Das muß es nicht, finde ich. Die zugrundeliegende Frage ist interessant und manch einem bereits begegnet, aber manch ein anderer hat sich möglicherweise noch überhaupt keine Gedanken darüber gemacht, schleppt aber dieserart einen Haufen potentieller Bugs mit sich herum. Deshalb ist nichts falsches oder peinliches daran, sie zu stellen. ;-)

(Danke für die Blumen, aber ich betrachte das nicht als "mein" Forum. :D )
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Manfred hat geschrieben:Aber bei einfachen Additionen, darf sowas nicht passieren. Es wird weder geteilt, noch multipliziert, noch gibt es irgendeinen Rest, der gerundet wird. Es bleibt bei 1,45 + 1,45 + 3,32 und das ergibt nach meinem Verständnis 6,22 und sonst nichts.
Ach wenn das Leben nur so einfach wäre ;) aber auch unnötige Arbeit kann das Ergebnis verpfuschen :D
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Tom,

die Frage als solche war mir auch nicht peinlich, aber der Weg. Ich habe den Quelltext Schritt für Schritt debugged und bin nicht auf diese verdammte UDF gekommen, weil die direkt in der VALID Abfrage des Gets war. Hätte ich mal direkt da reingeguckt, dann wäre alles wesentlich früher klar gewesen. Aber auch hier wieder wie immer: Tagelang rumgedoktert, nichts gefunden. Endlich die Frage ins Forum gestellt und dann die große Entdeckung innerhalb weniger Stunden.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Summenanzeige

Beitrag von Rolf Ramacher »

Hi Manfred,


in solchen Fällen lasse ich mir die Summen per msgbox anzeigen.
Den numerischen Wert wandle ich mit str um. Dann setze ich bei der msgbox folgendes Zeichen am anfang: < und dass > am ende.

Damit kann ich dann den vollen Inhalt der Variablen erkennen. Vielleicht ein Tip für die Zukunft.
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21192
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Rolf,

hätte ich so machen sollen, aber wie es eben so ist, wenn man denkt man schreibt richtig, dann schaut man auch nicht im Duden nach.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Antworten