Re: Fließkommazahlen auf Gleichheit prüfen
Zitat:
|
Re: Fließkommazahlen auf Gleichheit prüfen
Zitat:
ich glaube, ihr täuscht Euch da gewaltig. Currency ist nur vom Typ Extended. Vielleicht mit 8 Byte etwas ganauer als Double, ja .. aber immer noch ungenau .. folgendes Beispiel demonstriert es ...
Delphi-Quellcode:
var
cStart, c1, cadd : Currency; begin cStart := 10000000000000; cadd := 0.1; c1 := cStart; for i := 1 to 10 do begin c1 := c1 + eAdd; end; // for i if c1 = 10000000000001 then ShowMessage('Gleich = '); if SameValue(c1, 10000000000001) then ShowMessage('Gleich SameValue '); man sieht auch, wenn man z.b. rechnet: c1 := c1 + cAdd; und ins CPU Fenster geht, dass dort steht: uFrm_Main_XM.pas.1201: cas c1 := c1 + eAdd; 008BFEC1 DBAD90FEFFFF fld tbyte ptr [ebp-$00000170] 008BFEC7 D80DBC0D8C00 fmul dword ptr [$008c0dbc] 008BFECD DFAD28FFFFFF fild qword ptr [ebp-$000000d8] 008BFED3 DEC1 faddp st(1) 008BFED5 DFBD28FFFFFF fistp qword ptr [ebp-$000000d8] ich kenn mich zwar in Assembler nicht wirklich gut aus, aber "faddp" sind definitiv Fließkommezahlen .. |
Re: Fließkommazahlen auf Gleichheit prüfen
Currency ist ein skalierter Int64, nur das er über die FPU berechnet wird.
Delphi-Quellcode:
Procedure TForm2.Button1Click(Sender: TObject);
Var C: Currency; i: Int64 absolute C; i2: Integer; Begin For i2 := 0 to 100 do Begin C := i2 * 0.0531; Label1.Caption := CurrToStr(C); Label2.Caption := FloatToStr(i / 10000) + ' ' + IntToStr(i2); Application.ProcessMessages; Sleep(250); End; End; |
Re: Fließkommazahlen auf Gleichheit prüfen
Zitat:
hmmm ... warum rechnet er dannn mein Beispiel von oben nicht richtig? |
Re: Fließkommazahlen auf Gleichheit prüfen
also bei mir sieht es so aus ... k.A. wo bei dir das fmul her kommt :gruebel:
Delphi-Quellcode:
vielleicht fällt dir das fi... bzw. f.. auf > i für Integer
asm
// c1 := c1 + cAdd; fild qword ptr [&c1] fild qword ptr [&cAdd] faddp st(1) fistp qword ptr [&c1] wait // if c1 = Extended(10000000000001) then fld tbyte ptr [10000000000001] fild qurd ptr [&c1] fcompp fstsw ax sahf jnz ... end; ein Problem seh ich nur beim Vergleich ... wo Delphi aus dem 10000000000001 einen Extended macht ... typlose Umwandlungen wesehn nur in Integertypen und Extended (nach Currency wandelt Delphi keine Konstanten von alleine um) |
Re: Fließkommazahlen auf Gleichheit prüfen
Zitat:
Delphi-Quellcode:
[edit=mkinzler]Delphi-Tag eingefügt Mfg, mkinzler[/edit]
var
a, b: extended begin a:= 0.9; b:= 0.09; if 0.1*a=b then lblIstGleich.Caption:= 'ist gleich' else lblIstGleich.Caption:= 'ist ungleich'; end; Korrekt treibt man beim Vergleich von Gleitkommazahlen Epsilontik: const eps= 1e-14; // Definiert eine Umgebung für Rundungsfehler var a, b: extended; begin if a<-eps then.... // a<0 if Abs(a)<eps then... // a=0 if a>eps then... // a>0 if Abs(a-b)<eps then // a=b |
Re: Fließkommazahlen auf Gleichheit prüfen
edit
War ein Denkfehler, ich glaub, jetzt hab ichs verstanden :-) der Wert steht zwar drin, kann aber wiederum nur mit einer anderen Currency verglichen werden, weil wie Himitsu schon sagte, der Vergleich schief geht.
Delphi-Quellcode:
var
cStart, c1, c2, c3, c4, cmax, cadd : Currency; iAbsolute : Int64 absolute c1; begin cStart := 10000000000000; cadd := 0.1; c1 := cStart; for i := 1 to 10 do begin c1 := c1 + cAdd; end; // for i ShowMessage(IntToStr(iAbsolute)); // <- hier erscheint: 100000000000010000 (korrekt) if c1 = 10000000000001 then ShowMessage('Gleich = '); |
Re: Fließkommazahlen auf Gleichheit prüfen
Zitat:
Ich glaube, das war mein Fehler *duck* .. wenn man in das Quelltextbeispiel guckt, dann steht dort "eAdd" und nicht "cAdd" wie geplant .. eAdd war aber dummerweise ein Extended .. und das fmul ist die Multiplikation mit dem Skalierungsfaktor bei Currency (10000) sowas blödes .. :freak: ich nehm alles zurück, was ich zu Currency gesagt habe :-) :wall: |
Re: Fließkommazahlen auf Gleichheit prüfen
Zitat:
und drum hatte ich im anderem Thread auch 'ne reine Integerversion gepostet, da die FPU bzw. die Floattypen halt einiges an Ungenauigkeit mit sich bringt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:06 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