Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Delphi extrem falsche rundung
IhopeonlyReader - Di 09.04.13 14:57
Titel: Delphi extrem falsche rundung
Guten Tag,
ich habe mal eine Frage:
Delphi-Quelltext
1:
| FloatToStr( ( 1/((Now-NL)*24*60*60) )); |
(Now-NL)*86400 ist = die Differenz in Sekunden...
1/DifferenzInSekunden = wie oft es in der sekunde ausgeführt wurde..
soweit alles ok :)
allerdings:
Delphi-Quelltext
1: 2: 3:
| FloatToStr( ( 1/((Now-NL)*24*60*60) )); FloatToStr(Round ( 1/((Now-NL)*24*60*60) ); IntToStr(Round ( 1/((Now-NL)*24*60*60) ); |
da ich mich sehr über ein solchen Rundungsfehler wunderte, programmierte ich selber eine Rundungsfunktion
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| Function Runden(Zahl: Extended): Integer; var Ganzzahl: Integer; PosNeg: Integer; begin if Zahl>0 then PosNeg := 1 else PosNeg := -1; Ganzzahl := Trunc(Zahl); if Frac(Zahl)>=0.5 then Result := Ganzzahl+(1*PosNeg) else Result := Ganzzahl; end; |
jedoch:
Delphi-Quelltext
1: 2:
| FloatToStr(Runden( 1/((Now-NL)*24*60*60) ); IntToStr(Runden( 1/((Now-NL)*24*60*60) ); |
ein weiteres Wunder... darauf:
Delphi-Quelltext
1:
| FloatToStr(Trunc( 1/((Now-NL)*24*60*60) ); |
jetzt meine Frage: wieso wird aus 9.1 bei jeglicher rundungsart 91? wenn ich direkt Round(9.16746474946846...) schreibe, so ist das Ergebnis korrekt
Moderiert von
Narses: Beiträge zusammengefasstEdit: Auch
Delphi-Quelltext
1: 2: 3: 4: 5:
| var C: Extended; begin C := 1/((Now-NL)*24*60*60); IntToStr( Runden( C ) ); end; |
WasWeißDennIch - Di 09.04.13 15:14
Und wenn Du testhalber einmal SecondsBetween aus DateUtils verwendest?
Tranx - Di 09.04.13 15:31
Also, bei Delphi 5 wird so gerundet, wie zu erwarten ist. Keine falschen Ergebnisse (9,17 wird zu 9 gerundet). Allerdings habe ich now in eine zweite Variable NL2 gespeichert und nicht now - NL sondern NL2 - NL gerechnet.
P.S.: Auch bei Verwendung von now keine anderen Ergebnisse.
Mathematiker - Di 09.04.13 15:31
Hallo,
außer dass
Delphi-Quelltext
1: 2:
| FloatToStr(Round ( 1/((Now-NL)*24*60*60) ); IntToStr(Round ( 1/((Now-NL)*24*60*60) ); |
nicht stimmen können (schließende Klammern fehlen), habe ich Deine Routinen getestet:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| var nl:tdatetime; begin nl:=now-1/9.1762/86400; memo1.lines.add(FloatToStr( ( 1/((Now-NL)*24*60*60) ))); memo1.lines.add(FloatToStr(Round ( 1/((Now-NL)*24*60*60)))); memo1.lines.add(IntToStr(Round ( 1/((Now-NL)*24*60*60)))); memo1.lines.add(floattostr(1/9.1762/86400)); end; |
liefern die Rundungen korrekte(!) Werte.
Die letzte Zeile habe ich aufgenommen, um zu sehen, welcher Zeitraum eigentlich gemessen wird. Es sind 0,109 s.
Also bei mir funktioniert es ohne Probleme.
Du müsstest wahrscheinlich mehr Quelltext zeigen, um den eigentlichen Fehler zu lokalisieren.
Beste Grüße
Mathematiker
IhopeonlyReader - Di 09.04.13 15:33
FloatToStr( Round( 1000/MilliSecondsBetween(NL,Now) ))
Muss es dann sein, da es ca 0.1 sec liefert SecondsBetween 0 aus...
Aus dem oben genannten befehl kommt sogar 901 raus
WasWeißDennIch - Di 09.04.13 15:42
Was genau willst Du denn eigentlich berechnen?
IhopeonlyReader - Di 09.04.13 15:43
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;
type TForm1 = class(TForm) Timer1: TTimer; procedure Timer1Timer(Sender: TObject); private public end;
var Form1: TForm1; NL: TDateTime;
implementation
{$R *.dfm}
procedure TForm1.Timer1Timer(Sender: TObject); var T: String; begin T := 'FpS: '+ FloatToStr( Round( 1/((Now-NL)*24*60*60) )); ; NL := Now; Canvas.TextOut(0, ClientHeight- Canvas.TextHeight(T), T); end;
end. |
Moderiert von
Narses: Beiträge zusammengefasst WasWeißDennIch hat folgendes geschrieben : |
Was genau willst Du denn eigentlich berechnen? |
FpS
WasWeißDennIch - Di 09.04.13 15:48
Die bekommst Du doch mit einem Timer gar nicht heraus. Wenn, dann müsstest Du irgendwie z.B. 1000 Frames zeichnen und die dafür benötigte Zeit messen oder andersherum eine definierte Zeit lang so schnell wie möglich Frames zeichnen und diese zählen. Daraus ließen sich dann die FpS ermitteln.
IhopeonlyReader - Di 09.04.13 15:53
WasWeißDennIch hat folgendes geschrieben : |
Die bekommst Du doch mit einem Timer gar nicht heraus. |
Ich mache das so:
Startbutton: - DateTime abspeichern ( NL )
- Timer anmachen
im Timer:
- Text:= FloatToStr( Round( 1/((Now-NL)*24*60*60) ));
- NL := Now;
- zeichnen
- canvas.textout
Edit: FpS ist vielleicht nicht ganz korrekt.. sondern die Zeichnungen pro Sekunde
WasWeißDennIch - Di 09.04.13 16:01
Dazu müsstest Du die Zeichnungen aber auch zählen, sonst fehlen Dir doch die Berechnungsgrundlagen.
IhopeonlyReader - Di 09.04.13 16:03
Es geht darum, anzuzeigen, wieviele Zeichnungen in der Sek geschafft werden würden, wenn sie in der Geschwindigkeit (Zeit) gezeichnet werden, wie das letzte
WasWeißDennIch - Di 09.04.13 16:06
Und wie soll Dir ein Timer da weiterhelfen? Sofern ich den Code richtig überblicke, würde eine Änderung des Timer-Intervalls signifikant andere Ergebnisse liefern.
Mathematiker - Di 09.04.13 16:13
Hallo,
IhopeonlyReader hat folgendes geschrieben : |
Es geht darum, anzuzeigen, wieviele Zeichnungen in der Sek geschafft werden würden, wenn sie in der Geschwindigkeit (Zeit) gezeichnet werden, wie das letzte |
Mein Vorschlag:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| var Time1, Time2, Freq: Int64; wert : extended; begin QueryPerformanceFrequency(Freq); QueryPerformanceCounter(Time1);
QueryPerformanceCounter(Time2); wert:=1000*(Time2-Time1)/freq; label1.caption:=floattostrf(wert,ffgeneral,4,3)+' ms'; label2.caption:=floattostrf(1000/wert,ffgeneral,4,3)+' Bilder je s'; end; |
Beste Grüße
Mathematiker
IhopeonlyReader - Di 09.04.13 16:19
WasWeißDennIch hat folgendes geschrieben : |
Und wie soll Dir ein Timer da weiterhelfen? Sofern ich den Code richtig überblicke, würde eine Änderung des Timer-Intervalls signifikant andere Ergebnisse liefern. |
Wenn das Timer Intervall auf 1 steht?
Ich benutte den Timer eigentlich nur um eine Whilescleife zu vermeiden (damit sich das Programm nicht aufhängt), und da es auf die zeit zwischen Zeichnung 1 und Zeichnung 2 ankommt und das interval nun einmal dazwischen liegt, muss dies mitdrin sein
komischerweise:
T := 'FpS: '+ S + ' | '+Copy(S, 0, Pos(',', S)-1); // FpS: 9.0909 | 91
// oder manchmal auch: FpS: 9.909090| 910
FinnO - Di 09.04.13 16:26
IhopeonlyReader hat folgendes geschrieben : |
Wenn das Timer Intervall auf 1 steht?
Ich benutte den Timer eigentlich nur um eine Whilescleife zu vermeiden (damit sich das Programm nicht aufhängt)[...] |
Moin,
genau das ist kein sinnvoller Ansatz. Wenn du Code so oft wie möglich ausführen willst, musst du schon eine (Endlos)schleife benutzen. Damit sich dein Programm nicht "aufhängte" empfehle ich:
Delphi-Quelltext
1: 2: 3: 4: 5:
| while(true) begin doSth(); Application.ProcessMessages(); end; |
WasWeißDennIch - Di 09.04.13 16:28
Ein Timer-Interval von 1 kannst Du vergessen, nach meinem Kenntnisstand müsste das Minimum bei ca. 50 liegen. Außerdem ist ein Timer relativ ungenau, da er keine hohe Priorität hat. Wenn Dein Programm nicht blockieren soll, kommst Du m.M.n. mittelfristig nicht um einen Thread herum.
IhopeonlyReader - Di 09.04.13 16:44
dennoch stimmt die "Rundung" nicht.. vorallem bei dem Versuch mit Copy müsste es doch klappen! das heißt, der Compiler schreibt mein code irgendwie um :(
Mathematiker - Di 09.04.13 16:49
Hallo,
IhopeonlyReader hat folgendes geschrieben : |
dennoch stimmt die "Rundung" nicht.. |
Nein!!! Die Rundung stimmt (siehe weiter oben)! Derartige Fehler macht Delphi nicht.
Das Problem ist der Timer.
Da Du offensichtlich meine Beiträge ignorierst, klinke ich mich hier aus. :evil:
Beste Grüße
Mathematiker
WasWeißDennIch - Di 09.04.13 16:50
Das glaub ich kaum. Speicher doch zunächst Now() einmal in einer Variablen zwischen und benutz dann die zur Berechnung. Dann schreibe Dir eine Funktion für die Ermittlung der Sekunden und benutze diese. Deren Ergebnis wird dann gerundet. Wenn dabei unterschiedliche Ergebnisse herauskommen, dann stimmt etwas mit Deinem Delphi nicht, aber das steht IMO eher nicht zu erwarten.
IhopeonlyReader - Di 09.04.13 17:00
Mathematiker hat folgendes geschrieben : |
Da Du offensichtlich meine Beiträge ignorierst, klinke ich mich hier aus. :evil:
Beste Grüße
Mathematiker |
du versucht mich "umzuprogrammieren" nicht die Frage zu beantworten !
Ich möchte den Quelltext nicht ändern, sondern wissen warum die Rundung nicht stimmt... sonst müsste
Copy(T, 0, Pos(',', T)-1) bei T='3,161' eigentlich 3 ergeben und nicht 300 !
Mathematiker - Di 09.04.13 17:11
Hallo,
also ich habe noch einmal
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.Timer1Timer(Sender: TObject); var T: String; begin T := FloatToStr( ((Now-NL)*24*60*60) ); memo1.lines.add(T); T := 'FpS: '+ FloatToStr( 1/((Now-NL)*24*60*60) ); memo1.lines.add(T); T := 'FpS: '+ FloatToStr( Round( 1/((Now-NL)*24*60*60) )); memo1.lines.add(T); NL := Now; timer1.enabled:=false; end; |
mit einem Timerinterval = 1 und dem Start mit einem Buttonclick getestet. Ich erhalte auf meiner alten Mühle
Quelltext
1: 2: 3:
| 0,0160002149641514 FpS: 62,4991603075651 FpS: 62 |
und immer wieder ähnliche Werte, d.h., es wird vollkommen richtig gerundet. Hast Du nach der Anzeige den Timer deaktiviert?
Beste Grüße
Mathematiker
Tranx - Di 09.04.13 17:13
Mathematiker hat folgendes geschrieben : |
Hallo,
IhopeonlyReader hat folgendes geschrieben : | dennoch stimmt die "Rundung" nicht.. |
Nein!!! Die Rundung stimmt (siehe weiter oben)! Derartige Fehler macht Delphi nicht.
Das Problem ist der Timer.
|
Ich kann Steffen nur zustimmen, die Rundung ist nicht das Problem. Ohne Timer habe ich korrekte Werte erhalten. Möglicherweise funkt Dir der Timer dazwischen. Ich würde den rausnehmen und die Zeitmessung in einer Endlosschleife wie folgt programmieren:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| interface
var PROCABBRUCH : boolean = FALSE; implementation
procedure Form1.Btn1Click(Sender : TObject); begin PROCABBRUCH := true; end; : :
ok := TRUE; While ok do begin Application.ProcessMessages; if PROCABBRUCH then Exit; (Zeitmessungsroutine); end; |
Du benötigst einen Button (btn1 oder anders bezeichnet) Dieser erhält die ONClick-Prozedur wie oben. Bei jedem Schleifendurchgang wird die Prozedur Application.Processmessages durchlaufen, also wenn Du auf den Button drückst, wird in der OnClick-Prozedur die globale Variable PROCABBRUCH auf true gesetzt udn dann bei der Abbfrage logischerweise die Endlosschleife mit Exit abgebrochen.
IhopeonlyReader - Di 09.04.13 17:35
Um zu zeigen, dass nicht die ProgrammierART sondern Delphi einen Felder macht folgendes:
T := 'FpS: '+ FloatToStr( ( 1 / ((Now-NL)*24*60*60) )); //= 9.1
T := 'FpS: '+ FloatToStr( Round( 1 / ((Now-NL)*24*60*60) )); //= 91
T := 'FpS: '+ FloatToStr( Round( 1 / ((Now-NL)*24*60*60) )/1);//= 91
T := 'FpS: '+ FloatToStr( Round( 1 / ((Now-NL)*24*60*60) )/10); //=0.9
wenn round funktionieren würde, dann müsste wenn X/1 =91 x/10 =9.1 sein und nicht 0.9 !
WasWeißDennIch - Di 09.04.13 17:37
Wie sollen wir das nachvollziehen, wenn Du immer wieder auf now und nl zureifst, deren Werte wir nicht kennen?
IhopeonlyReader - Di 09.04.13 18:11
ich habe jetzt jede zeile für zeile "rausgenomen" (mit {}) und getestet, wann ein richtiges Ergebnis kam, und wann nicht..
Delphi-Quelltext
1: 2: 3: 4: 5:
| procedure DoIt; begin T := 'FpS: '+ FloatToStr( Round( 1/((Now-NL)*24*60*60) )); NL := Now; end; |
Wunder:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| if FesteFpS then begin if TryStrToFloat(FpSRate.Text, C) then if ( (Now-NL)*24*60*60*C > 1 ) then DoIt; end else begin DoIt; end; |
Hier kam 91 raus
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| if FesteFpS then begin if TryStrToFloat(FpSRate.Text, C) then if ( (Now-NL)*24*60*60*C > 1 ) then DoIt; end else begin end; |
Hier kam 9 raus (richtige)
Das Ergebnis war immer falsch, wenn festeFpS True war und DoIt bei if not FresteFpS then ausgeführt wurde... bei False kam ein richtiges Ergebnis raus bzw. wenn vor dem 2ten DoIt ein //stand gab es keinen Fehler... wisst ihr warum?
Mathematiker - Di 09.04.13 18:16
Hallo,
IhopeonlyReader hat folgendes geschrieben : |
wenn round funktionieren würde, dann müsste wenn X/1 =91 x/10 =9.1 sein und nicht 0.9 ! |
Also. Ich habe Deine Anweisungen im Timer(!) getestet. Ergebnis
Quelltext
1: 2: 3: 4:
| T := 'FpS: '+ FloatToStr( ( 1 / ((Now-NL)*24*60*60) )); //= FpS: 62,4991603075651 T := 'FpS: '+ FloatToStr( Round( 1 / ((Now-NL)*24*60*60) )); //= 62 T := 'FpS: '+ FloatToStr( Round( 1 / ((Now-NL)*24*60*60) )/1);//= 62 T := 'FpS: '+ FloatToStr( Round( 1 / ((Now-NL)*24*60*60) )/10); //=6,2 |
D.h., es wird richtig gerundet.
Irgendwie habe ich den Eindruck, dass Dein Delphi "eine Meise" hat.
Beste Grüße
Mathematiker
IhopeonlyReader - Di 09.04.13 18:19
Mathematiker hat folgendes geschrieben : |
Irgendwie habe ich den Eindruck, dass Dein Delphi "eine Meise" hat.
|
jap :D
wenn ich es so schreibe:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| if FesteFpS then begin if TryStrToFloat(FpSRate.Text, C) then if ( (Now-NL)*24*60*60*C > 1 ) then DoIt; end else begin DoIt; end; |
und mit F9 kompiliere, zeigt er 91 an
ABER !!!!!!!!!!
kompiliere ich mit F8 und drücke dann zur Laufzeit F9, so zeigt er 9 (richtig!) an....
Boldar - Di 09.04.13 18:34
An dieser Stelle schlage ich vor, du zeigst mal komplette Quelltexte, sonst wird das hier nichts mehr. Am besten minimalisiert auf den Fehler.
WasWeißDennIch - Di 09.04.13 18:35
Das klingt nach irgend einem Seiteneffekt. Genaueres dazu kann man aber mangels Source nicht sagen.
IhopeonlyReader - Di 09.04.13 18:51
Boldar hat folgendes geschrieben : |
An dieser Stelle schlage ich vor, du zeigst mal komplette Quelltexte, sonst wird das hier nichts mehr. Am besten minimalisiert auf den Fehler. |
Der Quelltext 3 Posts vor deinem ist alles.. alle andere hatte ich in {}... außer du willst noch sowas wie
Delphi-Quelltext
1: 2: 3: 4:
| procedure TForm1.Timer1Timer(Sender: TObject); begin end; |
dann sähe das so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TForm1 = class(TForm) Timer1: TTimer; FesteFpS: TCheckBox; FpSRate: TEdit; procedure Timer1Timer(Sender: TObject); private public end;
var Form1: TForm1; NL: TDateTime;
implementation
{$R *.dfm}
procedure TForm1.Timer1Timer(Sender: TObject); var T: String; C: Extended; procedure DoIt; begin T := 'FpS: '+ FloatToStr( Round( 1/((Now-NL)*24*60*60) )); NL := Now; end; begin if FesteFpS.Checked then begin if TryStrToFloat(FpSRate.Text, C) then if ( (Now-NL)*24*60*60*C > 1 ) then DoIt; end else begin DoIt; end; Canvas.TextOut(10, ClientHeight-Canvas.TextHeight(T), T); end;
end. |
Form besteht aus:
Timer1: TTimer; //Interval ist 1, er ist von anfang an Enabled := True
FesteFpS: TCheckBox;// Halt an und ausmachbar (von anfang an aus)
FpSRate: TEdit; //steht von anfang an 1 drin
Hierbei ensteht ein der Fehler... starte ich mit F8 und danach F9 funktioniert alles.. aber direkt F9 ist ein Fehler...
Wenn ich mit F8 zuerst gestartet habe, es dann klappt, dann Die Zahl im Edit größer als 70 wird, ist die angezeigte Zahl 66.. gehe ich nun wieder auf eine kleinere zahl z.B. 1, so wird die zahl 17 angezeigt.... (anstatt 1)
WasWeißDennIch - Di 09.04.13 19:15
Dann versuch doch erst einmal das, was ich vorher schon vorgeschlagen hatte (NOW ändert sich schließlich ständig):
Zitat: |
Speicher doch zunächst Now() einmal in einer Variablen zwischen und benutz dann die zur Berechnung. Dann schreibe Dir eine Funktion für die Ermittlung der Sekunden und benutze diese. Deren Ergebnis wird dann gerundet. |
Tranx - Di 09.04.13 19:47
Ich habe nun - bis auf die Prozedur TryStrToFloat, die ich durch einen Try .. except .. end-Konstrukt ersetzt habe, die Timerroutine geprüft. Es kommen bei mir keine Fehler beim Runden. 100,1 ergibt 100 und 50,56 ergibt 51.
Selbst wenn ich statt NL := now; schreibe: NL := now - 0.12/24/60/60, was ja bei der Differenz dann immer dazu führt, dass scheinbar eine Differenz von 0.12 Sekunden mindestens auftreten, wird korrekt gerundet (entwerder ist das Ergebnis 7 oder 8.
P.S. ich habe die Differenz NOW - NL und den ungerundeten Wert 1/((Now-NL)*86400) in T ausgegeben, und die gerundeten Werte stimmen immer!!!!
Ich weiß ehrlich nicht, wo der Fehler noch stecken soll.
Gerd Kayser - Di 09.04.13 20:20
Tranx hat folgendes geschrieben : |
Ich weiß ehrlich nicht, wo der Fehler noch stecken soll. |
Now liefert ein TDateTime zurück. Zwar kann TDateTime auch Millisekunden speichern, aber Now rundet immer auf volle Sekunden (siehe Delphi-Hilfe). Die Frage ist also, ob man mit der Differenz Now - NL überhaupt sinnvoll rechnen kann. Hinzu kommt noch der große Teiler "Now-NL)*86400".
Das hier funktioniert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TMainform.Button1Click(Sender: TObject); var Zeit : TDateTime; Zeit1 : TDateTime; Zeit2 : TDateTime; begin Zeit1 := TimeGetTime; Sleep(24); Zeit2 := TimeGetTime; Zeit := (Zeit2 - Zeit1); if Zeit > 0 then Label1.Caption := FloatToStr(Round((1 / Zeit) * 1000)) else Label1.Caption := 'Zeit = 0!'; end; |
Boldar - Di 09.04.13 20:26
Warum nicht gettickcount?
Gerd Kayser - Di 09.04.13 20:28
Boldar hat folgendes geschrieben : |
Warum nicht gettickcount? |
TimeGetTime hat eine höhere Auflösung.
Boldar - Di 09.04.13 20:35
Dann halt Queryperformancecounter. Btw. hat Timegettime nicht unbedingt eine höhere Präzision, und Auflösung ist sowieso das falsche Wort.
Zudem die Frage ob der TE das hier braucht, und nicht lieber einfach mehrere Frames messen möchte. Scheinbar hat der TE mit seinem Timer aber eh ein generelles Konzeptproblem.
Gerd Kayser - Di 09.04.13 20:44
Boldar hat folgendes geschrieben : |
Auflösung ist sowieso das falsche Wort. |
Zitat: |
The resolution of the GetTickCount function is limited to the resolution of the system timer, which is typically in the range of 10 milliseconds to 16 milliseconds. |
Quelle:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.85).aspx
Ich übersetze Resolution mit Auflösung. Aber das ist Erbsenzählerei.
WasWeißDennIch - Di 09.04.13 21:43
Boldar hat folgendes geschrieben : |
Zudem die Frage ob der TE das hier braucht, und nicht lieber einfach mehrere Frames messen möchte. Scheinbar hat der TE mit seinem Timer aber eh ein generelles Konzeptproblem. |
Das sag ich doch die ganze Zeit.
Mathematiker - Di 09.04.13 23:09
Hallo,
Boldar hat folgendes geschrieben : |
Dann halt Queryperformancecounter. |
Genau. Und deshalb wiederhole ich noch einmal meinen Vorschlag:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| var Time1, Time2, Freq: Int64; wert : extended; begin QueryPerformanceFrequency(Freq); QueryPerformanceCounter(Time1);
QueryPerformanceCounter(Time2); wert:=1000*(Time2-Time1)/freq; label1.caption:=floattostrf(wert,ffgeneral,4,3)+' ms'; label2.caption:=floattostrf(1000/wert,ffgeneral,4,3)+' Bilder je s'; end; |
Das funktioniert garantiert. Und wenn es nicht in die Zeichenroutine eingebaut werden soll, dann macht zwei Prozeduren, eine zum Start und eine zur Auswertung. Damit gibt's auch keinen Timer mehr, der offensichtlich nicht so will, wie er soll.
Beste Grüße
Mathematiker
Martok - Mi 10.04.13 07:01
Was die Auflösungen der verschiedenen Zeitfunktionen angeht... das müsste mal wer untersuchen. Oh wait,
hat ja schon wer gemacht [
http://www.entwickler-ecke.de/viewtopic.php?p=674768#674768] ;-)
Der Timer an sich wird schon funktionieren, hat unterhalb von einigen 100ms allerdings genau gar keine Wiederholgenauigkeit mehr. Das ist also durchaus möglich, dass manchmal sofort und manchmal erst nach relativ langer Zeit wieder ein Event kommt. Was als Renderschleife allerdings mehr oder weniger egal ist - ein Timer mir sehr kurzer Auflösung feuert praktisch genauso oft wie eine IdleLoop. Man kann dann allerdings auch direkt diese nehmen...
Und ansonsten das was Mathematiker sagt, siehe Link. An QPC führt kein Weg vorbei.
Momentanframeraten sind übrigens relativ nutzlos, die sollte man schon mitteln. FrameTime dagegen ist was, was durchaus seine Berechtigung hat.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!