Gibt es ein Limit für Gametime.TotalMilliseconds?

8

Die Spielzeit sollte immer länger werden, und die Gesamtmillisekunde wird der größte Wert sein. Wenn das Spiel also hypothetisch 1 Tag lang ausgeführt wird, sollte dieser Wert 86 400 000 betragen.

Dies ist wahrscheinlich kein Problem für die meisten Spiele, aber ich bin gespannt, ob es einen ausfallsicheren Mechanismus gibt, wenn er zu groß wird oder ob es überhaupt ein Limit gibt.

Alxander
quelle
Wer will das testen! : D
SpartanDonut

Antworten:

6

Ich fürchte, die Antworten hier verstehen nicht, dass die Grenze die DoubleMantisse ist. Der maximale vollständig genaue Wert für GameTime.TotalMillisecondsbeträgt tatsächlich ungefähr 10.000 Tage .

TimeSpanDie interne Darstellung ist die Tick, die als 1 / 10.000 Millisekunden definiert ist . TotalMillisecondsist a Double, das nur 2^53unterschiedliche Mantissenwerte darstellen kann . Nach 2 ^ 53 Ticks geht die Information verloren.

Das größte TimeSpan, das Doubleohne Genauigkeitsverlust dargestellt werden kann, ist:

2^53 ticks / 10000 ticksperms  900719925474 ms  10425 days
Sam Hocevar
quelle
1
Ich nicht mit dieser Antwort einverstanden. Die Anzahl der Ticks ist eine vorzeichenbehaftete 64-Bit-Ganzzahl. Die Anzahl der Millisekunden wird doppelt angezeigt, aber die Anzahl der Millisekunden in 2 ^ 63 Ticks beträgt weniger als 2 ^ 53, sodass kein Gleitkomma-Genauigkeitsverlust auftritt.
Jimmy
1
@ Jimmy: Es tut mir leid, dass Sie nicht einverstanden sind. Sie können jedoch keine 63 Bit in einer 53-Bit-Mantisse speichern, ohne an Genauigkeit zu verlieren. Und in einem Spiel benötigen Sie diese Genauigkeit von weniger als einer Millisekunde. Warum sollte sonst TotalMillisecondsein doubleund nicht ein sein long?
Sam Hocevar
1
63 Bit werden niemals in einer 53-Bit-Mantisse gespeichert! Hier ist meine Pseudo-Zeitspanne, die der Funktionsweise der realen ziemlich nahe kommt: gist.github.com/1753547 . long.MaxValue / TicksPerMillisecondwird niemals größer als 2 ^ 53 sein. TimeSpan verfolgt intern nichts als Double.
Jimmy
@ Jimmy: Es gibt etwas, das du nicht verstehst, aber ich weiß nicht, was es ist. Überprüfen Sie ideone.com/1XLuJ , um festzustellen , wie Ihre Klasse mit 60-Bit-Tick-Werten an Genauigkeit verliert.
Sam Hocevar
Das macht Sinn. Ich habe Integralwerte für Millisekunden angenommen. Ich habe meine eigene Antwort entfernt.
Jimmy
-1

Dies ist eher eine dumme Kleinigkeit, aber wenn Sie sich nicht für perfekte Präzision interessieren (wen interessiert es, wenn Sie eine Sekunde geben oder nehmen, wenn Sie über Jahrhunderte sprechen?), Dann TotalTimeist das auch ein Doppelgänger maximalen Wert , den es speichern ist 1.7976931348623157E+308.

Ich bin mir nicht sicher, wie Überläufe in C # funktionieren, aber wenn Sie das Spiel länger laufen lassen, würde es wahrscheinlich entweder auf so etwas zurückgehen -1.798*10^308 oder sich einfach nicht ändern. Es hängt auch davon ab, wie es intern implementiert wird.

Trotzdem ist diese Anzahl von Millisekunden ziemlich groß. Wenn man es mit dem hypothetischen Zeitalter des Universums vergleicht, ist es ... Äh ... Nun, es ist immer noch so ziemlich groß .

Natürlich, wie Sam sagte, wird die Zeit tatsächlich in Zecken gespeichert (Zehntel einer Nanosekunde?), So dass Sie nach einer " viel kürzeren " an die "Grenze" stoßen würden " Zeitspanne an . Es ist immer noch so etwas wie ein Würfel eines Googols, mal das Zeitalter des Universums.

Ich bin mir nicht sicher, wie GameTimegenau die Zeit gespeichert wird. Dies bedeutet auch, dass die TotalMillisecondsAusgabe möglicherweise nie "nahe" an ihren Maximalwert kommt. Wenn die Verpackungszeit in Tage und Jahre ist, wenn der Tick-Wert hoch genug wird, und nicht nur, wenn Sie den Getter anrufen, erhöht sich der Timer bis zum Maximalwert von double in Jahren , der sogar noch höher ist .

Wenn Ihr Spiel aus irgendeinem Grund so reichlich Inhalt haben sollte, dass Zeiträume erforderlich sind, in denen sehr viele Universen geboren werden und zugrunde gehen, um sie vollständig zu erforschen, gibt es spezielle Datentypen zum Speichern beliebig großer Zahlen. Java hat eine, BigDecimalderen Größe im Wesentlichen durch Ihren RAM (und durch den virtuellen Speicher, sogar Festplattenspeicher) begrenzt ist. Anscheinend hat C # nicht BigDecimal, aber es hat BigInteger.

Wenn Sie solch ein episch skaliertes Spiel machen, das zweifellos von den Göttern selbst gespielt werden soll, würden Sie wahrscheinlich zuerst die BigDecimalKlasse duplizieren und dann die GameTimeKlasse neu implementieren (oder sogar nur regelmäßig GameTimeden Wert Ihrer Klasse hinzufügen BigDecimal), um sie zu verwenden.

Superbest
quelle