Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TDateTime + Mikrosekunden (https://www.delphipraxis.net/80135-tdatetime-mikrosekunden.html)

MStoll 3. Nov 2006 12:59


TDateTime + Mikrosekunden
 
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

marabu 3. Nov 2006 13:12

Re: TDateTime + Mikrosekunden
 
Hallo Michael,

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

Grüße vom marabu

MStoll 3. Nov 2006 13:20

Re: TDateTime + Mikrosekunden
 
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.

himitsu 3. Nov 2006 13:33

Re: TDateTime + Mikrosekunden
 
Zitat:

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.

Amateurprofi 3. Nov 2006 22:48

Re: TDateTime + Mikrosekunden
 
Zitat:

Zitat von marabu
der Datentyp TDateTime arbeitet auf eine halbe Millisekunde genau

Zitat:

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.

marabu 4. Nov 2006 09:17

Re: TDateTime + Mikrosekunden
 
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

Amateurprofi 4. Nov 2006 15:42

Re: TDateTime + Mikrosekunden
 
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.

3_of_8 4. Nov 2006 16:02

Re: TDateTime + Mikrosekunden
 
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)

marabu 4. Nov 2006 16:23

Re: TDateTime + Mikrosekunden
 
Vielen Dank für die Erläuterungen. Ab Montag werde ich versuchen wieder selbst zu denken.

Zerknirschte Grüße

Amateurprofi 6. Nov 2006 04:50

Re: TDateTime + Mikrosekunden
 
Zitat:

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....

3_of_8 6. Nov 2006 07:11

Re: TDateTime + Mikrosekunden
 
Der 0.Januar 1900 ist der 31.Dezember 1899. ;)

Der Rest ist durchaus interessant, auf Wikipedia steht diese Information nicht (oder ich habe sie mehrfach überlesen).

EDIT: Eine Sache passt da nicht so ganz... Wie soll der Double dann die Zahl 0 aufnehmen?

Und ich würde die Zahl 7 eher so darstellen:

1 1100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 * 2^-50

Wäre dann in deiner Darstellung:

Mantisse: (1) 1100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 (erste 1 implizit)
Exponent: 111 1111 1100 1110

Wo ist mein Fehler?

Amateurprofi 7. Nov 2006 16:11

Re: TDateTime + Mikrosekunden
 
Zitat:

Zitat von 3_of_8
Der 0.Januar 1900 ist der 31.Dezember 1899. ;)

Ja, aber das Bezugsdatum von TDateTime ist der 30.Dezember 1899 (nicht der 31.)

Zitat:

Zitat von 3_of_8
Der Rest ist durchaus interessant, auf Wikipedia steht diese Information nicht (oder ich habe sie mehrfach überlesen).

Wikipedia ist schon eine tolle Sache. Jedoch würde ich das nicht gerade als Referenz betrachten, weil die Beiträge von jedem editiert werden können, also jeder seine persönliche Sicht der Dinge dort verewigen kann. (Leider gibt es so viele Leute die so viele Dinge wissen, die so nicht sind)

Zitat:

Zitat von 3_of_8
EDIT: Eine Sache passt da nicht so ganz... Wie soll der Double dann die Zahl 0 aufnehmen?

Wenn alle Bits des Exponenten und alle Bits der Mantisse = 0 sind, dann ist die Zahl = 0. Das Vorzeichen Bit entscheidet dann, ob die Zahl +0 oder -0 ist. (Die FPU kennt tatsächlich positive und negative 0.)

Zitat:

Zitat von 3_of_8
Und ich würde die Zahl 7 eher so darstellen:
1 1100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 * 2^-50

Wäre dann in deiner Darstellung:

Mantisse: (1) 1100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 (erste 1 implizit)
Exponent: 111 1111 1100 1110

Wo ist mein Fehler?

Dein Fehler ist, daß Du davon ausgehst, die Mantisse sei ein simples IntegerFeld.
Stelle Dir die Mantisse so vor, das hinter dem höchsten Bit (das implizit = 1 ist) ein Punkt steht.
Der "Exponent" gibt dann an, um wiewiel Stellen dieser Punkt nach rechts, oder bei negativem Exponenten nach links, verschoben werden muß. Die (nach der Verschiebung) links vom Punkt stehenden Bits bilden dann den Integer-Teil, die rechts vom Punkt stehenden Bits bilden den Nachkomma-Teil.
Beim Exponenten ist noch zu beachten, daß er, wie Intel sagt, "biased" ist. Der wirkliche Exponent ergibt sich aus Exponent minus Bias-Konstante (127 für Singles, 1023 für Doubles, 16383 für Extended).
Zur Darstellung der Zahl 7 :
Code:
0 10000000001 (1).1100000000000000000000000000000000000000000000000000
Also:
Sign           = 0
Biased Exponent = 401H = 1025D (biased)
True Exponent  = 2
Mantisse nach Verschiebung = (1)11.00000000000000000000000000000000000000000000000000
Und hier nochmal die komplette Definition für Singles, Doubles, Extendeds.
In der Tabelle ist "Integer" das höchste Bit der Mantisse und "Fraction" die auf "Integer" folgenden Bits.
Ein "." bedeutet, daß das vor dem "." stehende Zeichen wiederholt wird, um das Feld zu füllen.
Ein "x" beduetet, daß das betreffende Bit 0 oder 1 sein kann.

@3_of_8:
Ich habe mich bemüht, den folgenden Teil (hoffentlich) korrekt aus den Intel-Specs abzukupfern und zu interpretieren, gib Dir deshalb bitte auch Mühe ihn zu lesen und zu verstehen.
Die Intel-Specs kannst Du Dir hier holen: Intel Specs
Die Definitionen stehen in "Basic Architecture"

Code:
.                 Sign   Exponent        Integer Fraction
                   ----    ---------------  ------  --------------
+Unendlich        0       11.11            1       00.00
+Normale Zahlen   0       00.01 bis 11.10  1       00.00 bis 11.11
+Denormale Zahlen 0       00.00            0       00.01 bis 11.11
+0                 0       00.00            0       00.00
-------------------------------------------------------------------
-0                 1       00.00            0       00.00
-Denormale Zahlen 1       00.00            0       00.01 bis 11.11
-Normal Zahlen    1       00.01 bis 11.10  1       00.00 bis 11.11
-Unendlich        1       11.11            1       00.00
-------------------------------------------------------------------
SNaN              x      11.11            1       0x.xx (2)
QNaN              x      11.11            1       1x.xx
Indefinite        1       11.11            1       10.00
-------------------------------------------------------------------
Länge der Felder
Single            1       8                1 (1)  23
Double            1       11               1 (1)  52
Extended          1       15               1       63


(1) Bei Singles und Doubles wird das Integer-Bit nicht gespeichert.
    Es wird von der FPU implizit angenommen als = 1, außer für die
    Zahl 0 und für Denormale Zahlen. Ich vermute, daß der Exponent
    ausschlaggebend ist (Exponent=0 : I=0, Exponent<>0 : I=1).
   
(2) Mindestens 1 Bit (jedoch nicht das höchste) muß = 1 sein
Und hier das ganze noch mal in Textform :

Normale Zahlen sind die Zahlen, bei denen
1) Im Exponenten mindestens 1 Bit = 1 und mindestens 1 Bit = 0 ist.
2) Das Integer-Bit = 1 ist.

DeNormale Zahlen sind die Zahlen, bei denen
1) Der Exponent = 0 ist
2) Das Integer-Bit = 0 ist
3) Die Fraction &lt;&gt; 0 ist

0 Werte sind die Zahlen, bei denen
1) Der Exponent = 0 ist
2) Das Integer-Bit = 0 ist
3) Die Fraction = 0 ist

Unendlich-Werte sind die Zahlen, bei denen
1) Alle Bits des Exponenten = 1 sind
2) Das Integer-Bit = 1 ist
3) Die Fraction = 0 ist

SNaN Werte (="Signalling Not a Number") sind die Zahlen, bei denen
1) Alle Bits des Exponenten = 1 sind
2) Das Integer-Bit = 1 ist
3) Das höchste Bit der Fraction = 0 ist.
4) Mindestens 1 Bit der Fraction = 1 ist.

QNaN Werte (="Quiet Not a Number") sind die Zahlen, bei denen
1) Alle Bits des Exponenten = 1 sind
2) Das Integer-Bit = 1 ist
3) Das höchste Bit der Fraction = 1 ist.

Der Unterschied zwischen SNaNs und QNaNs ist, daß SNaNs immer eine FPU-Exception auslösen während QNaNs ohne FPU-Exception verarbeitet werden. FPU-Operationen, bei denen NaNs beteiligt werden liefern als Resultat immer eine QNaN. SNaNs können von der FPU nicht erzeugt werden, müssen bei Bedarf also per Software generiert werden.

3_of_8 7. Nov 2006 17:05

Re: TDateTime + Mikrosekunden
 
Klingt einleuchtend.

MStoll 7. Nov 2006 17:45

Re: TDateTime + Mikrosekunden
 
Ok, ich sehe, das Thema wird weiter diskutiert. Das freut mich ;)

Also um euch meine Verwendung näher zu erklären:
Es geht um Zeitnahme im Motorsport. Bisher lief alles korrekt (mit Millisekunden). Habe ich oft genug an zufällig ausgewählten Beispielen nachgerechnet.

Was verwende ich bei TDateTime-Werten?

Addition (+), Subtraktion (-),
Durschnittsberechnung, also Addition + später Division durch Integer (= Anzahl der Werte)
Maximum, Minimum (d.h. auch Sortieren)

An vorgegebenen TDateTime-Routinen verwende ich im wesentlichen nur:
EncodeTime, DecodeTime

WICHTIG scheint für euch ja zu sein: Ich codiere KEIN Datum rein, ich benutze TDateTime nur für Zeiten.

Wenn ich das recht sehe, kann ich dann also ne ziemlich hohe Genauigkeit erwarten?

Ich hatte noch eine Idee:
Ich wollte evtl. TDateTime durch extended ersetzen. Weiß jemand ob das Probleme mit EncodeTime bzw. DecodeTime macht? Bzw. haltet ihr dies für sinnvoll unter dem Vorhaben, mittels eigener Funktionen "zusätzlich" noch Mikrosekunden reinzucodieren? Werden diese dann bei Addition bzw. Subtraktion korrekt mit einberechnet? D.h. z.b. dass, wenn ich 3 Zeiten habe mit jeweils 400µs und diese addiere, dass dann später bei DecodeDate korrekt ne Millisekunde mehr rauskommt, als wenn ich keine Mikrosekunden reincodiert habe?

Ich bin das auch schon gedanklich selbst durchgegangen, allerdings bringt es sicherlich mehr Sicherheit, mal noch andere Meinungen einzuholen, denn bei Zeitnahme im Motorsport wären Rechenfehler denkbar schlecht.

Vielen Dank für weitere Tips.

Gruß
Michael

3_of_8 7. Nov 2006 18:07

Re: TDateTime + Mikrosekunden
 
Ja, wird es. Denn die DateUtils-Routinen erwarten TDateTime und keine Extendeds. Du könntest natürlich einen Typencast vornehmen, aber dadurch gewinnst du gar nichts.

Also entweder die Funktionen selbst neu schreiben oder lassen.

Wobei ich sagen muss, dass die Genauigkeit eines Singles oder Doubles auf jeden Fall ausreicht.

Soweit ich weiß, wenn du kein Datum reinkodierst, wird das implizit als 30.12.1899 angenommmen (Danke @Amateurprofi und Kopf->Wand) und dadurch hast du eine immense Genauigkeit. Rechnen wir das mal durch.
~9000000000000000 verschiedene Mantissen sind darstellbar.

Nehmen wir an, du rechnest nicht mit Zeiten >24h.
Das bedeutet, dass 1 die höchste Zahl ist, die erreicht wird.
Du kannst also bis auf 1/9000000000000000 Tag genau rechnen, also 1/(9*10^15) macht 9*10^-15.
9*10^-15d = 3,24*10^-11s
Das bedeutet, du bist sogar auf die Nanosekunde (eine Milliardstelsekunde) genau, genaugenommen sogar auf etwa 3 Pikosekunden genau.

Dürfte wohl ausreichen.

Khabarakh 7. Nov 2006 18:10

Re: TDateTime + Mikrosekunden
 
Zitat:

Zitat von 3_of_8
Der Rest ist durchaus interessant, auf Wikipedia steht diese Information nicht (oder ich habe sie mehrfach überlesen).

Darüber habe ich vor einiger Zeit etwas gelesen, rate mal auf welcher Seite ;) .
Bei wissenschaftlichen Artikeln kann man Wikipedia wahrscheinlich etwas mehr Vertrauen schenken, ansonsten gibt es immer noch am Seitendende die verlinkten Spezifikationen ;) .

3_of_8 7. Nov 2006 18:15

Re: TDateTime + Mikrosekunden
 
Tatsächlich, jetzt hab ichs auch gesehen. Muss ich wohl überlesen haben, so nach dem Motto "was momentan zu kompliziert für mich ist, ignoriere ich".

In meinem Mathe-Skript funktioniert das immer prima. :mrgreen:

MStoll 7. Nov 2006 18:23

Re: TDateTime + Mikrosekunden
 
Zitat:

Zitat von 3_of_8
Ja, wird es. Denn die DateUtils-Routinen erwarten TDateTime und keine Extendeds. Du könntest natürlich einen Typencast vornehmen, aber dadurch gewinnst du gar nichts.

Mal angenommen, ich mache also eine Funktion die etwa so aussieht:

Delphi-Quellcode:
function EncodeMyTime(h,m,s,ms,mys : word) : extended;
begin
     result := EncodeTime(h,m,s,ms);
     result := result + MysToTime(mys);
end;
und eine Prozedur, die etwa so aussieht:

Delphi-Quellcode:
procedure DecodeMyTime(t : extended; var h,m,s,ms,mys : word);
begin
     DecodeTime(TDateTime(t), h, m, s, ms);
     DecodeTime(t, mys);
end;
Was würde dadran schief gehen?

Mein Ziel ist es halt, die Mikrosekunden so einzukodieren, dass z.B. ihr Übertrag bei Addition sich entsprechend auf die Millisekunden auswirkt, d.h. im allgemeinen, dass sich diese Mikrosekunden in die Berechnungen nahtlos einfügen und ich die für die Dekodierung von Stunden, Minuten, Sekunden und Millisekunden weiterhin DecodeDate nehmen könnte.

3_of_8 7. Nov 2006 18:29

Re: TDateTime + Mikrosekunden
 
1. Was ist MysToTime?
2. Du hast einen impliziten Cast von Extended auf TDateTime, wenn du deinem Result das Ergebnis von EncodeTime zuweist. Das bedeutet, da verlierst du Genauigkeit. Das einzige, wo du eventuell was gewinnst, ist bei result:=result+MysToTime(...);, weil da addiert wird. Allerdings gewinnst du auch da nur was, wenn MysToTime entweder hohe oder sehr niedrige Werte liefert, zum Beispiel kleiner als 3 Pikosekunden.

Glaub mir, so tief kommst du nicht.

Es gibt übrigens nie Rechenfehler (bzw. nur sehr sehr selten) bei heutigen PCs. Nur eben Genauigkeitsfehler bei Gleitkommazahlen.

Nimm einfach TDateTime, das reicht LOCKER aus. Ich weiß nicht, wie genau im Rennsport gemessen wird, aber auf die Pikosekunde genau glaube ich nicht.

Nehmen wir an, der Abstand Rennwagen zu Messgerät beträgt 5 Meter. Die Lichtgeschwindigkeit nehmen wir vereinfacht mit 3*10^5 km/s an. Dann braucht das Licht für diese Strecke etwa 0,0000000166s, also 16 ns. Da wir auf 0,003 ns genau darstellen können, folgt daraus, dass du rein technisch gesehen gar nicht in den Bereich kommen könntest, in dem ein Double zu ungenau ist. Es sei denn du fährst Rennen, die mehrere Wochen dauern oder besitzt eine Tachyon-Lichtschranke.

MStoll 7. Nov 2006 18:36

Re: TDateTime + Mikrosekunden
 
War ja nur mal ein Gedankenspiel.

MysToTime wäre eben die Funktion, die Mikrosekunden in den entsprechenden Teil des Tages umwandelt.
Die kodiert die Mikrosekunden da noch rein. Sollte doch funktionieren, egal ob mit extended oder TDateTime.
Mir schon klar, dass EncodeTime nen impliziten TypeCast macht. Ich wollte ja mit dem Extended lediglich noch "Platz schaffen" für genauere Werte, wenn das allerdings schon mit TDateTime geht, ist das ja ok. ;)

Ich meinte mit Rechenfehler auch nich CPU-bedingte Rechenfehler, sondern solche, die auf Grund von Ungenauigkeiten entstehen könnten, wenn man viele Zeiten codiert und mit diesen rechnet, z.b. sie addiert. Also solche, die auf eine Ansammlung von Genauigkeitsproblemen zurückzuführen sind.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz