Existe um limite para Gametime.TotalMilliseconds?

8

O tempo de jogo deve sempre aumentar e o total de milissegundos será o maior valor. Portanto, se o jogo for hipoteticamente executado por 1 dia, esse valor deverá 86 400 000.

Provavelmente, isso não é um problema para a maioria dos jogos, mas estou curioso para saber se existe algum tipo de mecanismo à prova de falhas, se ele for muito grande ou se houver um limite.

Alxander
fonte
Quem quer testá-lo! : D
SpartanDonut

Respostas:

6

Receio que as respostas aqui não entendam que o limite é a Doublemantissa. O valor máximo totalmente exatoGameTime.TotalMilliseconds é de aproximadamente 10.000 dias .

TimeSpanA representação interna de Tické definida como 1 / 10.000 milissegundos . TotalMillisecondsé a Double, que pode representar apenas 2^53valores diferentes de mantissa . Após 2 ^ 53 ticks, há perda de informações.

Portanto, o maior TimeSpanque pode ser representado como um Doublesem perda de precisão é:

2^53 ticks / 10000 ticksperms  900719925474 ms  10425 days
sam hocevar
fonte
11
Eu não concordo com esta resposta. O número de ticks é um número inteiro de 64 bits assinado. O número de milissegundos é exposto como um dobro, mas o número de milissegundos em 2 ^ 63 ticks é menor que 2 ^ 53, portanto, não há perda de precisão de ponto flutuante.
6132 Jimmy
11
@ Jimmy: Lamento que você discorde. Mas você não pode armazenar 63 bits em uma mantissa de 53 bits sem perder a precisão, isso é um fato. E em um jogo, você precisa dessa precisão de menos de milissegundos. Caso contrário, por que TotalMillisecondsseria um doublee não um long?
sam Hocevar
11
63 bits nunca são armazenados em uma mantissa de 53 bits! Aqui está o meu pseudo-TimeSpan, que está bem próximo de como o real funciona: gist.github.com/1753547 . long.MaxValue / TicksPerMillisecondnunca será maior que 2 ^ 53. O TimeSpan, na verdade, não controla nada como um duplo internamente.
6136 Jimmy Jimmy
@ Jimmy: há algo que você não está entendendo, mas eu não sei o que é. Consulte ideone.com/1XLuJ para ver como sua classe perde precisão com valores de tick de 60 bits.
sam hocevar 6/02
isso faz sentido. Eu estava assumindo valores integrais por milissegundos. Eu removi minha própria resposta.
6136 Jimmy Jimmy
-1

Isso é um pouco mais trivial, mas se você não se importa com a precisão perfeita (quem se importa se você dá um segundo ou fala um pouco ao falar de séculos?), Então, como TotalTimeé um duplo, o valor máximo que ele pode armazenar é 1.7976931348623157E+308.

Não tenho certeza de como os estouros funcionam em C #, mas se você executar o jogo por mais tempo, acho que ele voltaria a algo como -1.798*10^308ou simplesmente não mudaria. Também depende de como é implementado internamente.

Dito isto, esse número de milissegundos é bastante grande. Se você comparar com a idade hipotética do universo, é ... Bem ... ainda é bem grande .

É claro que, como Sam disse, o tempo é realmente armazenado em ticks (décimos de nanossegundo?), Portanto, você entraria no "limite" após um período de tempo " muito mais curto ". Ainda é algo como um cubo de um googol vezes a idade do universo.

Não sei GameTimeexatamente como armazena o tempo, exatamente, portanto, isso também significa que você nunca verá a TotalMillisecondssaída "aproximar-se" do seu valor máximo. Embora, se for tempo de empacotamento em dias e anos sempre que o valor dos ticks for alto o suficiente, e não apenas quando você chamar o getter, o cronômetro aumentará até o valor máximo de double anos , o que é ainda mais alto .

Se, por alguma razão, seu jogo tiver conteúdo tão abundante que exija um período de tempo em que muitos universos nascem e perecem para explorar completamente, existem tipos de dados especializados para armazenar números arbitrariamente grandes. Java tem um BigDecimaltamanho cujo basicamente é limitado pela sua RAM (e através da memória virtual, até do espaço no disco rígido). Aparentemente, o C # não possui BigDecimal, mas possui BigInteger.

Se você fizer um jogo em escala épica, sem dúvida para ser jogado pelos próprios deuses, você provavelmente começará duplicando a BigDecimalclasse e, em seguida, reimplementando a GameTimeclasse (ou apenas adicionando periodicamente GameTimeo valor de sua BigDecimal) para usá-la.

Superbest
fonte