AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TDateTime + Mikrosekunden

Ein Thema von MStoll · begonnen am 3. Nov 2006 · letzter Beitrag vom 7. Nov 2006
Antwort Antwort
Seite 1 von 2  1 2      
MStoll

Registriert seit: 15. Nov 2005
131 Beiträge
 
Turbo Delphi für Win32
 
#1

TDateTime + Mikrosekunden

  Alt 3. Nov 2006, 12:59
hi,

weiß einer, ob der Datentyp TDateTime genau genug ist, um darin mittels einer extra Funktion auch Mikrosekunden zu speichern bzw. dass er dann, wenn ich bei den Mikrosekunden durch Addition einen Übertrag habe, diesen automatisch auf die Millisekunden anrechnet? Hat ansonsten einer ne Idee, wie ich Zeit + Datum + Mikrosekunden speichern kann, ohne das Rad neu zu erfinden? Ich habe ne große Applikations-Sammlung, die auf TDateTime basiert und bei der die Genauigkeit von Milli- auf Mikrosekunden umgestellt werden soll.

Zur Information:
Demnächst werde ich mir Turbo Delphi Pro kaufen, d.h. neue Sprachfeatures wie etwa Operator-Overloading in Records o.ä. könnte ich nutzen, falls jmd. darin ne Möglichkeit sieht.

Gruß
Michael
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: TDateTime + Mikrosekunden

  Alt 3. Nov 2006, 13:12
Hallo Michael,

der Datentyp TDateTime arbeitet auf eine halbe Millisekunde genau. Mehr zum Thema auch hier: klick

Grüße vom marabu
  Mit Zitat antworten Zitat
MStoll

Registriert seit: 15. Nov 2005
131 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: TDateTime + Mikrosekunden

  Alt 3. Nov 2006, 13:20
Danke.

Ich glaube, dann muss ich mir wirklich einen Record aus einem TDateTime und einem Integer für die Mikrosekunden machen, oder einen Int64 nehmen.

Ohweh, das bedeutet Arbeit.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.034 Beiträge
 
Delphi 12 Athens
 
#4

Re: TDateTime + Mikrosekunden

  Alt 3. Nov 2006, 13:33
Zitat von marabu:
der Datentyp TDateTime arbeitet auf eine halbe Millisekunde genau.
Nicht immer ... da die Genauigkeit vom Exponenten abhängt, kommt es auf das Jahr an.

Im Jahr 1601 (oder so) kommt man auch locker auf 0,1 Millisekunden. und in ein paar hundert Jahren kann man froh sein, wenn man da noch eine Sekunde rausbekommt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.057 Beiträge
 
Delphi XE2 Professional
 
#5

Re: TDateTime + Mikrosekunden

  Alt 3. Nov 2006, 22:48
Zitat von marabu:
der Datentyp TDateTime arbeitet auf eine halbe Millisekunde genau
Zitat von himitsu:
Im Jahr 1601 (oder so) kommt man auch locker auf 0,1 Millisekunden. und in ein paar hundert Jahren kann man froh sein, wenn man da noch eine Sekunde rausbekommt.
@marabu:
Nein, Du kannst 1/10 Millisekunde problemlos auflösen, jedenfalls im Bereich 01.01.0001 bis 31.12.9999, wobei beide Grenzwerte in der Praxis wohl keine Rolle spielen. Ersterer nicht, weil er vor unserer Datumsrechnung liegt.

@himitsu:
Wie im Kommentar für marabu gesagt, kann man mit TDateTime 1/10000 Sekunden auch im Jahr 9999 korrekt darstellen.

Wie komme ich zu dieser Aussage?:

Ein TDateTime-Wert ist ein Double-Wert, dessen Integer-Teil den laufenden Tag, gezählt ab 30.12.1899 (30.12.1899 = 0) abbildet. Der Nachkommateil gibt die Zeit am betreffenden Tag wieder.
Der 31.12.9999 hätte einen Integer-Teil = 2958465.
Um diesen Wert darzustellen werden 22 Bits der 52-Bit-Mantisse benötigt.
Somit bleiben für den Nachkomma-Teil 30 Bits verfügbar, mit denen 1073741824 unterschiedliche Werte verwaltet werden können. Geteilt durch 86400 (Sekunden/Tag) ergibt das 12427 verschiedene Werte pro Sekunde.
Das ist die Theorie.
Und wie sieht das in der Praxis aus ?:
Für eine Auflösung von 1/10000 s werden für einen Tag 86400*10000 = 864000000 "Einheiten" benötigt.
Wenn man nun den Integerwert eines Doubles auf 2958465 (=31.12.9999) setzt und dann für jede dieser 864000000 "Einheiten" (erfolgreich) prüft, ob es möglich ist, einen TDateTime-Wert zu generieren und anschließend wieder korrekt in Jahr,Monat,Tag, und "Einheit" umzuwandeln, dann kann man TDateTime für eine Auflösung von 1/10000 s verwenden.
Das habe ich geprüft - es funktioniert.

Wenn man allerdings mit solchen Werten rechnen will, kommt es zu Ungenauigkeiten.
Aber das passiert auch bei sehr viel geringeren Auflösungen.

Versuche mal folgendes (zugegebenermaßen etwas extremes Beispiel):

Delphi-Quellcode:
PROCEDURE TMain.Test;
var dt,dt3:TDateTime; i:integer;
begin
   dt:=Date;
   dt3:=1/3;
   for i:=1 to 3000000 do dt:=dt+dt3;
   ShowMessage(DateTimeToStr(dt));
end;
Du wirst sehen, daß da eine Abweichung von 4 s auftritt.

Fazit : Wer mit Zeiten wirklich exakt rechnen will, der sollte sich nicht auf TDateTime verlassen.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#6

Re: TDateTime + Mikrosekunden

  Alt 4. Nov 2006, 09:17
Hallo Klaus (und auch Frank),

stimmt - es ist nicht der Datentyp TDateTime, es sind die Datumsroutinen von Borland in Verbindung mit den enthaltenen Abbildungsfehlern (Basiswechsel 60 - 10 - 2), die eine (von mir beobachtete) Endgenauigkeit von etwa einer halben Millisekunde erwirken. Wenn Michael komplett eigene Routinen für die Zeitarithmetik verwendet, dann sollte es wohl funktionieren.

Aber hier noch eine Frage zu deinem Beitrag #5: Da ein Double-Wert garantiert 15 signifikante Dezimalstellen zur Verfügung stellt, sollte sogar das Rechnen mit Nanosekunden fehlerfrei möglich sein. Du hast in deinem Beitrag eine Rechengenauigkeit von 100 Mikrosekunden hergeleitet. Wo ist mein Denkfehler?

Freundliche Grüße
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.057 Beiträge
 
Delphi XE2 Professional
 
#7

Re: TDateTime + Mikrosekunden

  Alt 4. Nov 2006, 15:42
Hallo Achim,
Ein Double liefert (für dezimale Schreibweise) 15 (in einem eingeschränkten Bereich 16) signifikante Stellen.
Ich vermute Du interpretierst "15 signifikante Dezimalstellen" als "15 Stellen hinter der Dezimalpunkt".
Es sind aber 15 Ziffern für die komplette Zahl, also einschließlich der Ziffern vor dem Dezimalpunkt.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von 3_of_8
3_of_8

Registriert seit: 22. Mär 2005
Ort: Dingolfing
4.129 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: TDateTime + Mikrosekunden

  Alt 4. Nov 2006, 16:02
TDateTime ist ein Double-Typ, er besitzt eine Mantisse von 52 Bit. Dies bedeutet, er rechnet mit 52 Binärstellen, kann also maximal 2^52=4503599627370396 Mantissen darstellen.

Dies macht 15-16 Dezimalstellen, das bedeutet eine Genauigkeit auf die Mikrosekunde kann nur eingehalten werden, bis seit dem Bezugsdatum (0. Januar 1900) 2^52=4503599627370396 Mikrosekunden vergangen sind.

4503599627370396µs=4503599627370,396ms=4503599627, 370396s=52124d=142,7y

Also dürfte die Genauigkeit auf Mikrosekunde bis 17. September 2042 aufrecht erhalten bleiben.

(Wenn ich mich nicht verrechnet/verdacht habe)
Manuel Eberl
„The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.“
- Terry Pratchett
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#9

Re: TDateTime + Mikrosekunden

  Alt 4. Nov 2006, 16:23
Vielen Dank für die Erläuterungen. Ab Montag werde ich versuchen wieder selbst zu denken.

Zerknirschte Grüße
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.057 Beiträge
 
Delphi XE2 Professional
 
#10

Re: TDateTime + Mikrosekunden

  Alt 6. Nov 2006, 04:50
Zitat von 3_of_8:
TDateTime ist ein Double-Typ, er besitzt eine Mantisse von 52 Bit. Dies bedeutet, er rechnet mit 52 Binärstellen, kann also maximal 2^52=4503599627370396 Mantissen darstellen.

Dies macht 15-16 Dezimalstellen, das bedeutet eine Genauigkeit auf die Mikrosekunde kann nur eingehalten werden, bis seit dem Bezugsdatum (0. Januar 1900) 2^52=4503599627370396 Mikrosekunden vergangen sind.

4503599627370396µs=4503599627370,396ms=4503599627, 370396s=52124d=142,7y

Also dürfte die Genauigkeit auf Mikrosekunde bis 17. September 2042 aufrecht erhalten bleiben.

(Wenn ich mich nicht verrechnet/verdacht habe)
@3_of_8:

Im Prinzip ist das schon richtig, jedoch
1) Das Bezugsdatum bei TDateTime ist der 30.12.1899
2) Ein Double hat eine 53 Bit Mantisse, nicht 52 Bit.
Letzteres weiß ich auch erst seit heute - und ich denke das ist auch für diverse andere User eine Überraschung.

Wie funktioniert das, wenn 1 Bit fürs Vorzeichen, 11 Bits für den Exponenten und 53 Bits für die Mantisse, ingesamt also 65 Bits in 64 Bits untergebracht werden?:

Ganz einfach :
Anders als bei Extended-Werten, wird das höchste Bit der Mantisse bei Double und bei Single nicht gespeichert sondern implizit als = 1 angenommen (außer natürlich, wenn die Zahl 0 ist).

Zum Beispiel die Zahl 7 sieht, binär dargestellt, so aus
Code:
.       Sign Exponent       Mantisse
Double   0   10000000001     1100000000000000000000000000000000000000000000000000
Extended 0   100000000000001 1110000000000000000000000000000000000000000000000000000000000000
Auf Basis 53 Bit Mantisse habe ich mal zusammen gestellt für welche Zeiträume welche maximale Genauigkeiten erwartet werden können.
In unten stehender Tabelle bedeutet
FBits : Die Anzahl Bits, die für die Zeitangabe, also den Nachkomma-Teil benötigt werden.
IBits : Die Anzahl Bits, die für den Integerteil zur Verfügung stehen (=53-FBits).
Aus IBits habe ich dann die größte Zahl, die mit soviel Bits dargestellt werden kann, abgeleitet und hieraus das Von-Datum und das Bis-Datum. Die Datumsangaben habe ich auf min 01.01.0001 und max 31.12.9999 begrenzt.
Ob es in der Praxis tatsächlich funktioniert, alle möglichen Werte zu Codieren und beim Decodieren wieder auf den jeweiligen Ausgangswert zu kommen, habe ich nur für Millisekunden/10 geprüft.

Code:
Genauigkeit       Fbits IBits Von        Bis
Sekunden          17     36     01.01.0001  31.12.9999
Sekunden/10        20     33     01.01.0001  31.12.9999
Sekunden/100       24     29     01.01.0001  31.12.9999
MilliSekunden     27     26     01.01.0001  31.12.9999
MilliSekunden/10   30     23     01.01.0001  31.12.9999
MilliSekunden/100  34     19     18.07.0464  12.06.3335
MikroSekunden     37     16     26.07.1720  04.06.2079
MikroSekunden/10   40     13     27.07.1877  04.06.1922
MikroSekunden/100  43     10     12.03.1897  19.10.1902
NanoSekunden      47      6     28.10.1899  03.03.1900
NanoSekunden/10    50      3     23.12.1899  06.01.1900
NanoSekunden/100   53      0     30.12.1899  30.12.1899
Tja, jetzt ist es 04:47 Uhr und schlafen fällt heute aus....
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:56 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