Autor Beitrag
Zudomon
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Di 13.07.10 18:30 
Hallo,
ich würde gerne meine Objekte mit einem Zeitstempel versehen. Bisher habe ich dafür eine Variable vom Typ TSystemTime verwendet. Nun wollte ich das aber auf TDateTime refactorisieren und da liegt mein Problem. Sobald ich SystemTime über SystemTimeToDateTime in DateTime umwandel, wird DateTime extrem quantisiert. D.h. die Intervalle liegen bei etwa 3-5 Minuten. Das gleiche Phänomen habe ich, wenn ich DateTime einfach durch die Funktion Now erzeuge.

Kennt jemand dieses seltsame Verhalten oder kann mir einen Tipp geben, woran dies liegt?

Gruß
Zudo
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Di 13.07.10 18:48 
Ich hatte damals das Problem, das aus einer DLL die TDateTime Werte aus Now u.ä. nicht stimmten. Komplett falsche Werte, ohne dass ich was gefunden habe. Hab mir dann was eigenes gebastelt, das fast genauso war wie TDateTime aber funktionierte. Muss ich aber erst suchen. Irgendwo vergraben ;-)
Zudomon Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Di 13.07.10 18:54 
Andere sagen ja, dass TDateTime auf eine halbe Millisekunde genau arbeitet.

Ich habe mir bisher dafür auch was selbst gestrickt, aber ich würde nun auch gerne das vorhandene benutzen. Meine Vermutung ist, dass ich da nur irgendwas falsch mache oder nicht beachte.

Edit: Ich habe mal einen genaueren Blick in die Funktionen geworfen. In SystemTimeToDate berechnet er zwei Werte, einen für JahrMonatTag, der andere HourMinuteSecondMilliseconds. Der zweite Wert ist soweit ich das nachvollziehen kann, exakt. Aber sobald für den Resultwert beide Werte addiert werden, ist definitiv die Genauigkeit verschwunden. Das finde ich seltsam, weil der TDateTime Datentyp ja eigentlich ein Double-Wert ist. Kann es sein, dass der aus irgendeinem Grund da mit Single rechnet?
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Di 13.07.10 19:54 
Zudomon Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Di 13.07.10 20:03 
Danke, dass du dir die Mühe gemacht hast, mir deine Unit zu posten. Aber wie gesagt, ich würde da lieber gerne das bestehende benutzen. Zumal ich ja bisher auch eine selbstgestrickte Unit für meinen Zeitstempel benutzt hatte.

Was mir allerdings nun aufgefallen ist, irgendwie rechnet der in meinem großen Projekt nur mit Single Genauigkeit. In einem kleinen Test Projekt war dies nicht der Fall. Nun ist nur noch die Frage, warum Delphi das tut.
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Di 13.07.10 23:26 
Hast du mal ausprobiert, die selbe Rechnung, die in dem Testprojekt funktioniert, in deinem großem Projekt auszuprobieren?

Mal am besten jeweils den Code (den du WIRKLICH verwendet hast) posten. Vl ist irgendwo eine Konvertierung drin, die nicht sein sollte...
Zudomon Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Di 13.07.10 23:59 
Hier der Code, den ich in meinem großen Projekt und in meinem Testprojekt verwendet habe:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  opp1d, opp2d, resd: Double;
  opp1s, opp2s, ress: Single;
begin
  opp1d:=0.74367159605;
  opp2d:=40372;
  resd:=opp1d+opp2d;

  opp1s:=0.74367159605;
  opp2s:=40372;
  ress:=opp1s+opp2s;

  ShowMessage(floattostr(resd));
  ShowMessage(floattostr(ress));
end;


In dem Testprojekt gibt er mir aus:
40372,7436715961 (Double)
40372,7421875 (Single)

In dem großen Projekt:
40372,7406860337 (Double)
40372,7406860337 (Single)

Ich verwende Turbo Delphi 2006. Habe auch mal probiert, alle Units, die ich in dem großen Projekt verwende, in dem Testprojekt einzubinden. Aber ohne Erfolg, ich erhalte exakt das gleiche Ergebnis. In den Projekteinstellungen scheint auch alles gleich zu sein. Irgendwie kann ich mir nicht erklären, was da schief läuft. :(
Zudomon Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mi 14.07.10 01:39 
Der Fehler ist gefunden!! :D

Es lag letztendlich an DirectX. Wenn man nicht das Flag D3DCREATE_FPU_PRESERVE angibt, dann überschreibt DirectX die Precision für sämtliche Gleitkommaoperationen in dem aktuellen Thread.