2013-12-20 4 views
0

У меня интересная, но странная проблема с моим таймером игр. Кажется, что миллисекунды прекрасно работают. Однако, когда я пытаюсь применить std::chrono::seconds, я неожиданно получаю 0.000000 при кастинге на поплавок.Chrono Timer Неправильно преобразовывает секунды

Мой таймер следующим образом:

#include <iostream> 
#include <time.h> 
#include <chrono> 


class Timer 
{ 
public: 

    typedef std::chrono::high_resolution_clock Time; 
    typedef std::chrono::milliseconds ms; //<--If changed to seconds, I get 0.00000 
    typedef std::chrono::duration<float> fsec; 

    std::chrono::high_resolution_clock::time_point m_timestamp; 

    float currentElapsed; 

    Timer() 
    { 
      m_timestamp = Time::now(); 
    } 

    float getTimeElapsed() 
    { 
     return currentElapsed; 
    } 

    void Tick() 
    { 
     currentElapsed = std::chrono::duration_cast<ms>(Time::now() - m_timestamp).count(); 
     m_timestamp = Time::now(); 
    } 

public: 
    //Singleton stuff 
    static Timer* Instance(); 
    static void Create(); 
}; 

Таймер получает галочкой раз за кадр. Так, например, я обычно получаю около 33 мс за кадр. 33ms/1000 = 0.033s секунд, поэтому должно быть достаточно места для хранения.

Любые идеи о том, что может произойти?

Любая помощь очень ценится!

EDIT: К сожалению, секунды, миллисекунды не

+0

Где именно отображается '0.000'? Вы говорите, что бросили на поплавок - где? –

+0

currentElapsed - это float, поэтому std :: chrono :: duration . Насколько я понимаю, внутренний формат не является плавающим. CurrentElapsed переменная заканчивается 0.0f. Если миллисекунды, то возвращается ненулевое значение. –

ответ

1

std::chrono::seconds и др. все определены как имеющие интегральные представления (C++ 11 §20.11.2 [time.syn]). При преобразовании длительности высокого разрешения длительности низкого разрешения, вы выполняете целочисленное деление с в результате усечения, например,

using namespace std::chrono; 
assert(duration_cast<seconds>(milliseconds{999}) == seconds{0}); 

Вы можете избежать этого усечения пути переключения на представление с плавающей запятой перед тем масштабирования вместо из после:

using namespace std::chrono; 
currentElapsed = duration_cast<duration<float,std::milli>>(Time::now() - m_timestamp).count(); 

(Demo at coliru)

еще лучше, store currentElapsed as a duration to keep the "units" associated with the magnitude:

class Timer { 
    typedef std::chrono::high_resolution_clock Time; 
    typedef std::chrono::duration<float> duration; 

    Time::time_point m_timestamp; 
    duration currentElapsed; 

public: 
    Timer() : m_timestamp(Time::now()) {} 

    duration getTimeElapsed() const { 
     return currentElapsed; 
    } 

    void Tick() { 
     auto now = Time::now(); 
     currentElapsed = now - m_timestamp; 
     m_timestamp = now; 
    } 
}; 

 Смежные вопросы

  • Нет связанных вопросов^_^