Autor Beitrag
monty.ms
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 47



BeitragVerfasst: So 15.05.05 15:44 
hallo

ich hab mal eine kleine frage zu diesem Code:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var x1,x2:real;
begin
x1:=0.2;
x2:=x1-0.2;
label1.Caption:=floattostr(x2);
end;


.. der ist ja eigentlich richtig, doch warum kommt als Ergebnis nicht 0 raus, sondern 1,1099519E-17 ??
ist das ein fehler von delphi?

ps: sry wenn es hier schonmal war und nochmals sry wenn das der falsche Bereich ist =)

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.
Moderiert von user profile iconraziel: Topic aus Sonstiges verschoben am So 15.05.2005 um 16:00


Zuletzt bearbeitet von monty.ms am So 15.05.05 16:10, insgesamt 1-mal bearbeitet
Fabian W.
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1766

Win 7
D7 PE
BeitragVerfasst: So 15.05.05 16:01 
Das Problem hatte ich auch mal, aber nur in kleinen Bereichen 0.1-0.1, aber da kam auch immer schrott raus.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 15.05.05 16:04 
Benütze statt real extended.
Das ist übrigens kein Fehler von Delphi; das wird über die Hardware gerechnet. Die Zahl die du erhältst ist unterhalb der Maschinengenauigkeit. Ich nehm mal die Ungenauigkeit kommt vom Runden oder sowas.
Die Zahl 0.2 lautet im Binärsystem 0.001100110011... (periodisch).
Je nach dem bei welchem Schritt der Berechnung genau gerundet wird, kommt's halt anders raus.

user profile iconFabian W.: Was denn für "Schrott"? Die Abweichung ist doch minim.
Fabian W.
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1766

Win 7
D7 PE
BeitragVerfasst: So 15.05.05 16:20 
Und was ist bei extended jetzt anders?
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 15.05.05 16:29 
Extended ist noch ein bisschen genauer als Double-Precision (real).
Fabian W.
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1766

Win 7
D7 PE
BeitragVerfasst: So 15.05.05 16:32 
rechnet aber auch per Maschiene? Dann kann ich gleich runden wenn real schon
Zitat:
minim
ist...
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 15.05.05 16:41 
user profile iconFabian W. hat folgendes geschrieben:
rechnet aber auch per Maschiene? Dann kann ich gleich runden wenn real schon
Zitat:
minim
ist...
Ja, auch Extended geht über die FPU. Der Unterschied zu Double ist, dass bei Extended alle Zahlen vor der Berechnung in den FPU Stack geladen werden müssen, bevor eine Berechnung stattfinden kann. So ist die ganze Sache symmetrisch und es wird immer beim gleichen Schritt gerundet. Bei Double ist dies nicht unbedingt notwendig und somit geschieht dort die Rundung nicht immer symmetrisch.
Könnte mich aber täuschen, bin kein FPU Experte.

Zur zweiten Bemerkung: Ich sagte, die Abweichung zum korrekten Resultat ist minim. Wenn du die Zahl richtig formatiert darstellst (siehe z.B. floattostrf) dann sieht man den kleinen Fehler auch nicht. Aber gegen die Tatsache, dass der Rechner nicht exakt rechnen kann, kannst du nichts tun.
Fabian W.
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1766

Win 7
D7 PE
BeitragVerfasst: So 15.05.05 16:57 
Wie macht das dann der taschenrechner?
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 15.05.05 17:02 
Dein Taschenrechner rechnet entweder Dezimal oder rundet beim Anzeigen der Zahlen die letzten 3 Stellen weg (oder keines der beiden).
So, das waren jetzt bald genug deiner Fast-Off-Topic Fragen, findeste nicht auch? Im Prinzip geht es hier ja um user profile iconmonty.ms. Wenn du dich so sehr für die Sache interessierst, schau mal im Google unter "Floating Point Arithmetic IEEE".
Fabian W.
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1766

Win 7
D7 PE
BeitragVerfasst: So 15.05.05 17:10 
Also, gut. Die Frage war ja geklärt.
juppinger
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 50



BeitragVerfasst: Di 03.05.11 12:15 
Hallo zusammen,

prima dass ich den gleichen Fehler in meinem Programm entdeckt habe bzw. darauf hingewiesen wurde und in diesem Forum sofort etwas gefunden habe :)

Aber jetzt kommt's:

Ich habe eine Version des Programms erstellt, in der ich von REAL auf EXTENDET umgestellt habe. - Mehr habe ich wirklich nicht gemacht, ausser den Datentyp geändert.

Tests auf diversen (neueren) PCs mit untersch. Windows-Versionen klappt ( Fehler behoben, Programm rechnet genau ).

Jetzt habe ich das Programm auf einem älteren PC laufen lassen (Win XP), und da tritt der Fehler noch immer auf - obwohl der Zahlentyp umgestellt wurde.

Hat da jemand einen Ansatz?

Danke im Vorfeld,
jup
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 03.05.11 12:34 
Es ist doch genau. Die Ungenauigkeit merkst du ja nicht, weil die so weit hinter dem Komma durch die interne Darstellung entsteht.

Zur Ausgabe musst du natürlich darauf achten, dass du das dann richtig ausgibst. Stichwort RoundTo oder Format oder... ;-)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 03.05.11 13:19 
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Di 03.05.11 13:46 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Hier ist die Erklärung: www.michael-puff.de/...el/Fliesskomma.shtml
Und was soll das erklären? Hier wird doch gar nicht auf Gleichheit getestet und es treten keine Rechenfehler auf! Das Ausgangsproblem scheint paradox, weil mit unterschiedlichen Genauigkeiten gerechnet wird und 0.2 halt weder real noch extended exakt darstellbar ist. Das Problem tritt nicht auf zB für 0.125 oder 0.25.

Beispiel mit Dezimalsystem. "Real" = 5 Stellen, "Extended" = 8 Stellen, Rechnung wird "Extended" gemacht:

ausblenden Quelltext
1:
2:
3:
x1,x2: real; 
x1 := 0.33333333;      // x1 = 0.333333
x2 := x1 - 0.33333333;  // x2 = 0.333333 - 0.33333333 = -0.00000333
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 03.05.11 14:15 
Es ist doch egal, ob auf Gleichheit getestet wird oder nicht. Lies den Artikel. Da erkläre ich, warum sich manche Dezimalzahlen nicht ein zu eins im Binärsystem abbilden lassen. Und genau das ist das Problem, warum x1:=0.2; x2:=x1-0.2; eben nicht null ergibt.
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Di 03.05.11 14:33 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Es ist doch egal, ob auf Gleichheit getestet wird oder nicht. Lies den Artikel. Da erkläre ich, warum sich manche Dezimalzahlen nicht ein zu eins im Binärsystem abbilden lassen. Und genau das ist das Problem, warum x1:=0.2; x2:=x1-0.2; eben nicht null ergibt.
Unsinn! Wie ja schon festgestellt wurde, ist es exakt gleich 0, wenn extended gerechnet wird. Darüber hinaus sind alle Gleitkommadifferenzen x-y exakt, wenn x und y Gleitkommazahlen mit y/2 <= x <= 2*y sind (wenn kein Underflow auftritt). Wenn Du das nicht weißt oder nicht glaubst, suche doch einfach mal nach "Sterbenz Lemma" (Dies ist zB Theorem 11 in D. Goldbergs "What Every Computer Scientist Should Know About Floating-Point Arithmetic", zB via cr.yp.to/2005-590/goldberg.pdf)
KleinesPferd
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 29



BeitragVerfasst: Di 03.05.11 14:37 
Es ist eine Eigenschaft von Fließkommazahlen (float), dass sie generell Näherungswerte der uns gebräuchlichen Zahlen sind.

Eine FLOAT besteht aus einem VorzeichenBit, gefolgt von einer Mantisse (oder Basis) und einem Exponenten.

1. Problem: Null-Darstellung
Mathematisch ist
edit weil falsch war:
irgendwas^0

immer 1. Somit ist die Mantisse nie Null. Es bleibt nun übrig, die Basis sehr klein zu wählen, oder den Exponenten entsprechend klein zu machen. -> Führt zu einer Rundung.

2. Problem:
Desweiteren ist es eine Herausforderung, eine Basis UND einen Exponenten zu finden, die genau 0.2 ergeben. Oder Pi, oder jede andere uns geläufige Zahl.

Für uns ist eine Zahl mit 17 mal die 0 als Nachkommastelle eine Null. Für den PC nicht ;)

Grüße

(p.s. alles rein akademisch)


Zuletzt bearbeitet von KleinesPferd am Di 03.05.11 15:17, insgesamt 1-mal bearbeitet
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Di 03.05.11 14:53 
user profile iconKleinesPferd hat folgendes geschrieben Zum zitierten Posting springen:
...
1. Problem: Null-Darstellung
Mathematisch ist 0^(irgendwas) immer 1. Somit ist die Mantisse nie Null. Es bleibt nun übrig, die Basis sehr klein zu wählen, oder den Exponenten entsprechend klein zu machen. -> Führt zu einer Rundung.
Falsch: erstens ist 0^(irgendwas) fast immer 0 für irgendwas >=0, mit der Ausnahme 0^0. Zweitens ist 0 = 0*Basis^irgendwas, normalerweise nimmt man aber als Exponent 0.
user profile iconKleinesPferd hat folgendes geschrieben Zum zitierten Posting springen:
Für uns ist eine Zahl mit 17 mal die 0 als Nachkommastelle eine Null. Für den PC nicht ;)
Falsch: Das ist auch für den PC so. Außerdem ist 17 nur die ungefähre Genauigkeit für Double (Extended hätte ca. 19); aber selbstverständlich sind viel kleinere Zahlen darstellbar bis ca 10^-308.
Gerd Kayser
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Di 03.05.11 15:01 
user profile iconKleinesPferd hat folgendes geschrieben Zum zitierten Posting springen:
Mathematisch ist 0^(irgendwas) immer 1.

Meine Schulzeit liegt zwar fast 40 Jahre zurück, aber das kann nicht stimmen, denn 0 * 0 ist 0.
Du meinst wohl "x hoch 0", denn das wäre immer 1 (wenn ich mich noch richtig daran erinnere).
KleinesPferd
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 29



BeitragVerfasst: Di 03.05.11 15:13 
Ich seh grad, da hab ich was verwechselt *arg* Besonders weil die Mantisse nie 0 ist, sondern zw 1 und 2.

Ja ich meine x^0 ist 1 ... Ich bitte um Entschuldigung.


Auch wollte ich nicht auf die Feinheiten von Double oder Extended oder sonst was hinaus, sondern den generellen Aufbau einer Fließkommazahl anreißen. Damit der TE nachvollziehen kann, warum dort E-17 steht. Denn nicht jeder der hier im Forum liest und schreibt, ist dem Prinzip Fließkommazahl mächtig. Und nicht jeder der den Text von cr.yp.to überfliegt, versteht auf Anhieb den Sinn dahinter. Wenn jemals die Zeit gefunden wird sich da reinzulesen.

Mag ja sein, das mit extended viele Annehmlichkeiten eingezogen sind. Grundprinzip ist trotzdem geblieben.

Auch wenn dein Hinweis richtig ist, finde ich, das du mit Kanonen auf Spatzen schiesst ;)