Chrono Timer does not translate seconds properly

I have an interesting but strange problem with my game timer. Milliseconds seem to work just fine. However, when I try to apply the std::chrono::seconds , I unexpectedly get 0.000000 when casting to float.

My timer is as follows:

  #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(); }; 

The timer gets a mark once per frame. So, for example, I usually get about 33 ms per frame. 33ms / 1000 = 0.033s seconds, so there should be a lot of space to store this place.

Any ideas on what could happen?

Any help is much appreciated!

EDIT: Sorry seconds, not milliseconds

0
source share
1 answer

std::chrono::seconds et al. all are defined as having integral representations (C ++ 11 ยง20.11.2 [time.syn]). When you convert a high-resolution duration to a low-resolution duration, you perform integer division with the resulting truncation, for example

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

You can avoid this truncation by switching to a floating point view before scaling, and not after:

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

( Demo on coliru )

Better yet, save currentElapsed as duration to save the "units" associated with the value :

 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; } }; 
+1
source

Source: https://habr.com/ru/post/1243335/


All Articles